4

In my Laravel 5/vuejs 2.6 I upload an image with the vue-upload-component and am sending a requested image blob I try to save it with the controller code like :

    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) ) {

As result, I have an image uploaded, but it is not readable. The source file has 5 Kib, the resulting file has 5.8 Kib and in the browser's console I see the blobs path as

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

Have do I convert my blob to save it correctly?

MODIFIED : a bit more detailed : In vue file I send request using 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) => {
                });

and this.previewCustomerRegister.avatarFile.blob has value: "blob:http://local-hostels2.com/91a18493-36a7-4023-8ced-f5ea4a3c58af" where http://local-hostels2.com is my hosting... I set this value to preview image defined as :

            <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"
            >

and when previewCustomerRegister.avatarFile.blob is assigned with uploaded file I see it in preview image. I show control with saving function in first topic but when I tried to opened my generated file with kate, I found that it has content of my container file resources/views/index.blade.php...

What I did wrong and which is the valid way ?

MODIFIED BLOCK #2 : I added 'Content-Type' in request

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

but with it I got validation errors in my control, as I define control action with request:

public function store(CustomerRegisterRequest $request)
{

and in 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;
    }
}

In routes/api.php defined :

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

In the console of my bhrowser I see : https://i.sstatic.net/HUfhO.jpg, https://i.sstatic.net/o7U56.jpg

I suppose that something is wrong in axios header ? without 'Content-Type' defined my validation rules work ok...

MODIFIED BLOCK #3

I managed to make fetch of blob with metod like :

            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);
            });

In objectURL and self I see proper values : https://i.sstatic.net/AQDuX.jpg

1) But checking data on server in laravel's control I see the same values I had at start of my attemps to upload image:

[avatar_filename] => patlongred.jpg [avatar] => blob:http://local-hostels2.com/d9bf4b66-42b9-4990-9325-a72dc8c3a392

Have To manipulate with fetched bnlob in some other way ?

2) If I set :

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

I got validation errors that my data were not correctly requested...

?

4
  • Please look at MODIFIED Commented Aug 15, 2019 at 14:32
  • I still search for decision. Who use vue-upload-component component files uploading in vuejs with laravel in control ? How do you save blob image uploaded with vue-upload-component component? Please, share working example... Commented Aug 21, 2019 at 3:39
  • This is a dupe of: stackoverflow.com/questions/47809402/… Commented Aug 26, 2019 at 11:26
  • Do you really need to paste that much codes? Commented Jul 7, 2020 at 8:48

2 Answers 2

3

You're using request type as application/json hence you won't be able to save the image this way, for a file upload a request type should be multipart/form-data in this case you'll need to send request as

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) => {});
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for your help! Please look at MODIFIED BLOCK #2
as per your MODIFIED BLOCK #2 you're sending request as imgur.com/a/wJEbBnP which is still wrong, you cannot send a JSON object in request with 'multipart/form-data', also you can't send Blob URL to upload file, you need to send File uploaded, for more details you can refer to this thread stackoverflow.com/a/22087178/11950301
as I use vue-upload-component and it keeps url of blob(I made preview of this uploaded file on my form) that seems tricky how can I to convurt blob into File uploaded ?
you can probably do fetch(blobUrl).then(res => res.blob()).catch(err => { //handle err })
but you are not sending request correctly yet, it will always throw error this way. You cant sent http request with multipart/form-data using JSON you should use new FormData(); to create a form object and then send the request
|
2

Thank you for your help!

Valid decision was :

        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);
        });

and common laravel's file uploading functionality :

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.