9

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

4
  • Well Axios isn't the only library out there...what about Vue Resource github.com/pagekit/vue-resource/issues/267 ? Yes I know they said..but for me it still works pretty fine Commented Apr 23, 2017 at 20:12
  • 1
    The referred link says that node.js doesn't support FormData objects. Nor should it really, FormData is a browser construct. Axios supports submitting FormData from a browser just fine. codepen.io/Kradek/pen/aWmomM?editors=1010 Commented Apr 23, 2017 at 22:45
  • @BertEvans - Many thanks for the input. Yes it works both with axios and new XMLHttpRequest() using formData(). Is FormData an good solution ?. caniuse.com/#search=FormData Commented Apr 24, 2017 at 9:18
  • @Sumanta Depends on your use case, but generally it's fine. Commented Apr 24, 2017 at 16:28

3 Answers 3

13

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.

Sign up to request clarification or add additional context in comments.

Comments

8

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.

1 Comment

Indeed, this is more convenient, IMHO
2

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

1 Comment

Adding "boundary" to headers solved my problem (after 3-4 hours). Thank you so much!

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.