Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to submit "multipart/form-data" from VueJs

I am using VueJs / axios in frontend and multer in nodejs for a simple file upload to work.

So far all tries has been unsuccessful. While this can be achieved in 100 ways in angular 1/2 using ng-upload and other similar plugins. But VueJs seems to be lacking this basic functionality. Based on my research axios doesnt support "multipart/form-data". Ref https://github.com/mzabriskie/axios/issues/789 .

multer and other nodejs libraries seems to work with "multipart/form-data" seamlessly from angular 1/2. However same functionality is not working from VueJs.

Is there any other alternative other than axios which support "multipart/form-data" aka -- WebKitFormBoundary ??

Many Thanks

like image 732
Sumanta Avatar asked Apr 23 '17 18:04

Sumanta


3 Answers

I found two ways of achieving this in VueJs. There might be more.

Option 1. Using Axios. Based on answer by Bert Evans above

const formData = new FormData();
  formData.append("file", _file);
  formData.append("id", 7878);
  axios.post("/api/uploadFile", formData)
    .then(function (result) {
      console.log(result);
    }, function (error) {
      console.log(error);
    });

Option 2. Using Native XMLHttpRequest()`

 var formData = new FormData();
  formData.append("file", _file);
  formData.append("id", 7878);
  var request = new XMLHttpRequest();
  request.open("POST", "/api/uploadFile");
  request.send(formData);
  request.onreadystatechange = function () {
    if (request.readyState === 4) {
      if (request.status === 200 && request.statusText === 'OK') {
        console.log('successful');
      } else {
        console.log('failed');
      }
    }
  }

An interesting point of FormData() browser support here caniuseFormData

Also for those trying like me to make it work with content-type = "multipart/form-data" with axios. It won't work.

like image 100
Sumanta Avatar answered Oct 09 '22 11:10

Sumanta


You can use FormData for that and it is pretty easy.

Let me show you an example:

// html    
<button ref="uploadBtn" @onChange="upload">Upload Files</button>

// js
methods: {
    upload () {
        let files = this.$refs.uploadBtn.files
        let formData = new FormData()

        // if you want to upload multiple files at once loop 
        // through the array of files
        formData.append('attachment', files[0])
        axios.post(url, formData).then(response => ...)
    }
}

This should do the trick and you don't really need a 3rd party plugin for that.

like image 23
Helder Lucas Avatar answered Oct 09 '22 10:10

Helder Lucas


i have also faced the an issue where i have to send some other info along with image. i would like to share what i did. I am trying to upload image, kind, name and eventID.

let logo1 = new FormData
logo1.append('image', this.logo1)
logo1.append('kind', 'logo1')
logo1.append('name', this.$refs.logo1.files[0].name )
logo1.append('eventID',eventID)


axios.post(`/upload`, logo1,
        
  {
    headers:{
      'Authorization' : `${token}`,
      'Content-Type': `multipart/form-data; boundary=${logo1._boundary}` 
 },    

 }).then((res) => {

     console.log(res)


}).catch((error) => {

    console.log(error)

})

Note: The postdata param format should be (url , FormData) and not (url, {data: FormData})

like image 38
vithu shaji Avatar answered Oct 09 '22 09:10

vithu shaji