2

My Question is similar to this which doesn't have an answer. I tried to search many other places but still don't have an answer.

I'm trying to download file using Axios in VueJs as a blob:

return new Promise((resolve, reject) => {
      Axios.get(`${fileDownloadUrl}`,
        { responseType: 'blob' } // Blob doesn't handle errors
      ).then(response => {
        let byteData = response.data
        var blob = new Blob([byteData], {type: response.headers['content-type']})
        let fileName = _.split(response.headers['content-disposition'], '=')
        FileSaver.saveAs(blob, fileName[1])
        resolve(fileName[1])
      },
        error => {
          console.log(error.response.data) // returns Blob - error message from service is not handled
          reject(error.response.data)
        }
      )

I removed the { responseType: 'blob' } from the above code and tried again, I get the error message now but the file downloaded doesn't have any content, it's a blank data.

How do I download the file and handle the error response returned by the service?

iQuestProgrammer
  • 309
  • 2
  • 5
  • 18

3 Answers3

3

Using vue-resource solved this issue. Although it will be retiring in future releases, I couldn't find a better way to do it as Axios was not able to handle it.

Following is the code:

main.js

import VueResource from 'vue-resource'
Vue.use(VueResource)

service.js

return new Promise((resolve, reject) => {
  VueResource.http.get(`${fileDownloadUrl}`,
    { responseType: 'blob' }
  ).then(response => {
    methods.downloadFile(response, cid)
    resolve(cid)
  }, error => {
    reject(error)
  })
})

Hope this helps.

iQuestProgrammer
  • 309
  • 2
  • 5
  • 18
2
import axios from "axios";

// It is needed to handle when your response is not Blob (for example when response is json format)
axios.interceptors.response.use(
    response => {
        return response;
    },
    error => {
        if (
            error.request.responseType === 'blob' &&
            error.response.data instanceof Blob &&
            error.response.data.type &&
            error.response.data.type.toLowerCase().indexOf('json') != -1
        ) {
            return new Promise((resolve, reject) => {
                let reader = new FileReader();
                reader.onload = () => {
                    error.response.data = JSON.parse(reader.result);
                    resolve(Promise.reject(error));
                };

                reader.onerror = () => {
                    reject(error);
                };

                reader.readAsText(error.response.data);
            });
        }
        return Promise.reject(error);
    }
);


// Now you can get response in both Blob and json format
axios.get(
    url,
    {
        responseType: 'blob'
    }
).then(response => {
    // Your Code

}).catch((error) => {
    // Your Code
    // You can get error in json format
});
geeekfa
  • 1,169
  • 1
  • 10
  • 15
0

May I know is it possible to use post instead of get in the following request

Axios.get(${fileDownloadUrl}, { responseType: 'blob' }

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 07 '22 at 11:56