mary
mary

Reputation: 121

Axios for Vue not uploading image to server

When I want to upload an image and send the other data using FormData. Axios seems to serialize the image. Therefore, when i upload the image using Axios, the image is inside the body's payload as a string. As a result, I'm unable to use Multer on the server side to retrieve the uploaded image from the request.

This is my Vue code:

export default () {
  name: 'app',
  data () {
    image: ''
  },
  methods: {
      onFileChange (e) {
      var files = e.target.files || e.dataTransfer.files
      if (!files.length) {
        return
      }
      // console.log(files[0])
      // var x = files[0]
      return this.createImage(files[0])
      // return new Buffer(x)
    },
    createImage (file) {
      // var image = new Image()
      var reader = new FileReader()
      var vm = this

      reader.onload = (e) => {
        // vm.image = e.target.result
        vm.image = file.toString('base64')
        console.log(vm.image)
      }
      reader.readAsDataURL(file)
    },
    submitStaff () {
      const formData = new FormData()
      formData.append('file', this.image)
      formData.append('name', this.data.name)
      formData.append('username', this.data.username)
      formData.append('password', this.data.password)

      axios.post('api/myApiUrl', formData)
        .then(function (response) {
          console.log(response)
        })
        .catch(function (error) {
          console.log(error)
        })    
  }
}
<input type="file" @change="onFileChange">

Request Payload (Error with Vue) enter image description here

Request Payload (Successful with Postman) enter image description here

How do i fix this? Thank you!

Upvotes: 1

Views: 3924

Answers (1)

Leandro Bortolotto
Leandro Bortolotto

Reputation: 111

I faced a problem related to it and in my case I was setting Content-Type as a default configuration for all my requests, doing this:

axios.defaults.headers.common['Content-Type'] = 'application/json [or something]';

And, as I remember, part of my solution was to remove this configuration to make the upload works. I just erased that line from my code and all requests worked well. As soon I removed it, I could notice that my headers request changed to this (see attached image and notice the Content-Type entry):

enter image description here

Another thing you should be alert is the field name to your <input type="file" name="file">. I have a java backend expecting a parameter named as "file", so, in my case, my input file HAS to be set as "file" on my HTML and on my server side, like this:

    public ResponseEntity<Show> create(
        @RequestParam("file") MultipartFile file, 
        RedirectAttributes redirectAttributes) { ... }

Observe the entry @RequestParam("file")...

And in the HTML file:

    <form enctype="multipart/form-data" novalidate v-if="isInitial || isSaving">
    <div class="well">
        <div class="form-group">
            <label>* Selecione o arquivo excel. O sistema fará o upload automaticamente!</label>
            <div class="dropbox">
              <input type="file" single name="file" :disabled="isSaving" @change="filesChange($event.target.name, $event.target.files); fileCount = $event.target.files.length"
                accept="application/vnd.ms-excel" class="input-file">
                <p v-if="isInitial">
                  Solte o arquivo excel aqui<br> ou clique para buscar.
                </p>
                <p v-if="isSaving">
                  Carregando arquivo...
                </p>
            </div>
        </div>
    </div>
</form>

You also can take a look at this tutorial, it my help you: https://scotch.io/tutorials/how-to-handle-file-uploads-in-vue-2

I hope it helps you!

Upvotes: 1

Related Questions