【问题标题】:Saving blob image in laravel's controller在 laravel 控制器中保存 blob 图像
【发布时间】:2019-08-28 18:09:27
【问题描述】:

在我的 Laravel 5/vuejs 2.6 中,我使用 vue-upload-component 上传图像并发送请求的图像 blob 我尝试使用控制器代码保存它:

    if ( !empty($requestData['avatar_filename']) and !empty($requestData['avatar_blob']) ) {
        $dest_image = 'public/' . Customer::getUserAvatarPath($newCustomer->id, $requestData['avatar_filename']);

        $requestData['avatar_blob']= str_replace('blob:','',$requestData['avatar_blob']);
        Storage::disk('local')->put($dest_image, file_get_contents($requestData['avatar_blob']));
        ImageOptimizer::optimize( storage_path().'/app/'.$dest_image, null );
    } // if ( !empty($page_content_image) ) {

结果,我上传了一张图片,但它不可读。 源文件有 5 Kib,生成的文件有 5.8 Kib,在浏览器的控制台中,我看到 blob 路径为

avatar_blob: "blob:http://local-hostels2.com/91a18493-36a7-4023-8ced-f5ea4a3c58af"

我必须转换我的 blob 以正确保存它吗?

修改: 更详细一点: 在 vue 文件中,我使用 axios 发送请求:

               let customerRegisterArray =
                    {
                        username: this.previewCustomerRegister.username,
                        email: this.previewCustomerRegister.email,
                        first_name: this.previewCustomerRegister.first_name,
                        last_name: this.previewCustomerRegister.last_name,
                        account_type: this.previewCustomerRegister.account_type,
                        phone: this.previewCustomerRegister.phone,
                        website: this.previewCustomerRegister.website,
                        notes: this.previewCustomerRegister.notes,
                        avatar_filename: this.previewCustomerRegister.avatarFile.name,
                        avatar_blob: this.previewCustomerRegister.avatarFile.blob,
                    };
                console.log("customerRegisterArray::")
                console.log(customerRegisterArray)

                axios({
                    method: ('post'),
                    url: window.API_VERSION_LINK + '/customer_register_store',
                    data: customerRegisterArray,
                }).then((response) => {
                    this.showPopupMessage("Customer Register", 'Customer added successfully ! Check entered email for activation link !', 'success');
alert( "SAVED!!::"+var_dump() )
                }).catch((error) => {
                });

并且 this.previewCustomerRegister.avatarFile.blob 具有值:“blob:http://local-hostels2.com/91a18493-36a7-4023-8ced-f5ea4a3c58afhttp://local-hostels2.com 是我的主机... 我将此值设置为预览图像定义为:

            <img
                class="img-preview-wrapper"
                :src="previewCustomerRegister.avatarFile.blob"
                alt="Your avatar"
                v-show="previewCustomerRegister.avatarFile.blob"
                width="256"
                height="auto"
                id="preview_avatar_file"
            >

当 previewCustomerRegister.avatarFile.blob 被分配上传文件时,我在预览图像中看到它。 我在第一个主题中展示了带有保存功能的控件,但是当我尝试用 kate 打开生成的文件时,我发现它 有我的容器文件资源/视图/index.blade.php 的内容...

我做错了什么,哪个是有效的方法?

修改版块 #2: 我在请求中添加了“Content-Type”

axios({
  method: ('post'),
  url: window.API_VERSION_LINK + '/customer_register_store',
  data: customerRegisterArray,
  headers: {
    'Content-Type': 'multipart/form-data'
  }

但有了它,我的控件中出现了验证错误,因为我使用请求定义了控件操作:

public function store(CustomerRegisterRequest $request)
{

在 app/Http/Requests/CustomerRegisterRequest.php 中:

<?php

namespace App\Http\Requests;

use App\Http\Traits\funcsTrait;
use Illuminate\Foundation\Http\FormRequest;
use App\Customer;
class CustomerRegisterRequest extends FormRequest
{
    use funcsTrait;

    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        $request= Request();
        $requestData= $request->all();

        $this->debToFile(print_r( $requestData,true),'  getCustomerValidationRulesArray $requestData::');
        /* My debugging method to write data to text file 
        and with Content-Type defined above I see that $requestData is always empty
        and I got validations errors
         */

        // Validations rules 
        $customerValidationRulesArray= Customer::getCustomerValidationRulesArray( $request->get('id'), ['status'] );
        return $customerValidationRulesArray;
    }
}

在 routes/api.php 中定义:

Route::post('customer_register_store', 'CustomerRegisterController@store');

在浏览器的控制台中,我看到:https://imgur.com/a/0vsPIsahttps://imgur.com/a/wJEbBnP

我想 axios 标头有问题吗?如果没有定义“Content-Type”,我的验证规则可以正常工作...

修改版块 #3

我设法使用方法获取 blob,例如:

            var self = this;

            fetch(this.previewCustomerRegister.avatarFile.blob) .then(function(response) {
                console.log("fetch response::")
                console.log( response )

                if (response.ok) {
                    return response.blob().then(function(myBlob) {
                        var objectURL = URL.createObjectURL(myBlob);
                        // myImage.src = objectURL;
                        console.log("objectURL::")
                        console.log( objectURL )

                        console.log("self::")
                        console.log( self )



                        let customerRegisterArray =
                            {
                                username: self.previewCustomerRegister.username,
                                email: self.previewCustomerRegister.email,
                                first_name: self.previewCustomerRegister.first_name,
                                last_name: self.previewCustomerRegister.last_name,
                                account_type: self.previewCustomerRegister.account_type,
                                phone: self.previewCustomerRegister.phone,
                                website: self.previewCustomerRegister.website,
                                notes: self.previewCustomerRegister.notes,
                                avatar_filename: self.previewCustomerRegister.avatarFile.name,
                                avatar: objectURL,
                            };

                        console.log("customerRegisterArray::")
                        console.log(customerRegisterArray)

                        axios({
                            method: 'POST',
                            url: window.API_VERSION_LINK + '/customer_register_store',
                            data: customerRegisterArray,
                            // headers: {
                            //     'Content-Type': 'multipart/form-data'  // multipart/form-data - as we need to upload with image
                            // }
                        }).then((response) => {
                            self.is_page_updating = false
                            self.message = ''
                            self.showPopupMessage("Customer Register", 'Customer added successfully ! Check entered email for activation link !', 'success');
                            alert( "SAVED!!::")
                        }).catch((error) => {







  self.$setLaravelValidationErrorsFromResponse(error.response.data);
                            self.is_page_updating = false
                            self.showRunTimeError(error, this);
                            self.showPopupMessage("Customer Register", 'Error adding customer ! Check Details fields !', 'warn');
                            // window.grecaptcha.reset()
                            self.is_recaptcha_verified = false;
                            self.$refs.customer_register_wizard.changeTab(3,0)
                        });


                    });
                } else {
                    return response.json().then(function(jsonError) {
                        // ...
                    });
                }
            }).catch(function(error) {
                console.log('There has been a problem with your fetch operation: ', error.message);
            });

在 objectURL 和 self 中,我看到了正确的值:https://imgur.com/a/4YvhbFz

1) 但是在 laravel 的控制下检查服务器上的数据时,我看到了与开始尝试上传图片时相同的值:

[头像文件名] => patlongred.jpg [头像] => blob:http://local-hostels2.com/d9bf4b66-42b9-4990-9325-a72dc8c3a392

必须以其他方式对获取的 bnlob 进行操作?

2) 如果我设置:

  headers: {
    'Content-Type': 'multipart/form-data'
  }

我收到验证错误,表明我的数据未正确请求...

?

【问题讨论】:

  • 请看已修改
  • 我仍在寻找决定。谁使用 vue-upload-component 组件文件在 vuejs 中通过 laravel 控制上传?如何保存使用 vue-upload-component 组件上传的 blob 图像?请分享工作示例...
  • 你真的需要粘贴那么多代码吗?

标签: laravel-5 vuejs2 image-uploading


【解决方案1】:

您使用的请求类型为application/json,因此您将无法以这种方式保存图像,对于文件上传,请求类型应为multipart/form-data,在这种情况下您需要发送请求为

let customerRegisterArray = new FormData();
customerRegisterArray.put('username', this.previewCustomerRegister.username);
customerRegisterArray.put('email', this.previewCustomerRegister.email);
....
customerRegisterArray.put('avatar', this.previewCustomerRegister.avatarFile);

console.log("customerRegisterArray::")
console.log(customerRegisterArray)

axios({
  method: ('post'),
  url: window.API_VERSION_LINK + '/customer_register_store',
  data: customerRegisterArray,
  headers: {
    'Content-Type': 'multipart/form-data'
  }
}).then((response) => {
     this.showPopupMessage("Customer Register", 'Customer added successfully !Check entered email for activation link !', 'success');
     alert( "SAVED!!::"+var_dump() )
}).catch((error) => {});

【讨论】:

  • 感谢您的帮助!请看 MODIFIED BLOCK #2
  • 根据您的MODIFIED BLOCK #2,您以imgur.com/a/wJEbBnP 发送请求,这仍然是错误的,您不能在请求中使用“multipart/form-data”发送 JSON 对象,您也不能发送 Blob URL 上传文件,需要发送上传文件,详细可以参考本帖stackoverflow.com/a/22087178/11950301
  • 因为我使用 vue-upload-component 并且它保留了 blob 的 url(我在我的表单上预览了这个上传的文件),这似乎很棘手如何将 blob 转换为上传的文件?
  • 你可以做fetch(blobUrl).then(res =&gt; res.blob()).catch(err =&gt; { //handle err })
  • 但是您还没有正确发送请求,它总是会以这种方式抛出错误。您不能使用JSON 发送带有multipart/form-data 的http 请求,您应该使用new FormData(); 创建一个表单对象,然后发送请求
【解决方案2】:

感谢您的帮助!

有效的决定是:

        var self = this;

        fetch(this.previewCustomerRegister.avatarFile.blob) .then(function(response) {
            if (response.ok) {
                return response.blob().then(function(myBlob) {

                    var objectURL = URL.createObjectURL(myBlob);

                    let data = new FormData()
                    data.append('username', self.previewCustomerRegister.username)
                    data.append('email', self.previewCustomerRegister.email)
                    data.append('first_name', self.previewCustomerRegister.first_name)
                    data.append('last_name', self.previewCustomerRegister.last_name)
                    data.append('account_type', self.previewCustomerRegister.account_type)
                    data.append('phone', self.previewCustomerRegister.phone)
                    data.append('website', self.previewCustomerRegister.website)
                    data.append('notes', self.previewCustomerRegister.notes)
                    data.append('avatar_filename', self.previewCustomerRegister.avatarFile.name)
                    data.append('avatar', myBlob)

                    axios({
                        method: 'POST',
                        url: window.API_VERSION_LINK + '/customer_register_store',
                        data: data,
                        headers: {
                            'Accept': 'application/json',
                            'Content-Type': 'multipart/form-data'  // multipart/form-data - as we need to upload with image
                        }
                    }).then((response) => {
                        self.is_page_updating = false
                        self.message = ''
                        self.showPopupMessage("Customer Register", 'Customer added successfully ! Check entered email for activation link !', 'success');
                        alert( "SAVED!!::123")
                        // self.$router.push({path: '/'});
                    }).catch((error) => {
                        self.$setLaravelValidationErrorsFromResponse(error.response.data);
                        self.is_page_updating = false

                        self.showRunTimeError(error, this);
                        self.showPopupMessage("Customer Register", 'Error adding customer ! Check Details fields !', 'warn');
                        window.grecaptcha.reset()
                        self.is_recaptcha_verified = false;
                        self.$refs.customer_register_wizard.changeTab(3,0)
                    });


                });
            } else {
                return response.json().then(function(jsonError) {
                    // ...
                });
            }
        }).catch(function(error) {
            console.log('There has been a problem with your fetch operation: ', error.message);
        });

以及常见的laravel文件上传功能:

$customerAvatarUploadedFile = $request->file('avatar');
...

【讨论】:

    猜你喜欢
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 2013-01-03
    • 2020-10-08
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    相关资源
    最近更新 更多