当 responseType 是 blob 使用 Vuejs 时如何处理错误?

How do I handle errors when responseType is blob using Vuejs?

我的问题类似于 this,但没有答案。我试图搜索许多其他地方,但仍然没有答案。

我正在尝试使用 VueJs 中的 Axios 作为 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)
        }
      )

我把上面代码中的{ responseType: 'blob' }去掉再试一次,现在我得到了错误信息,但是下载的文件没有任何内容,是一个空白数据。

如何下载文件并处理服务返回的错误响应?

使用 vue-resource 解决了这个问题。虽然它将在未来的版本中退休,但我找不到更好的方法来做到这一点,因为 Axios 无法处理它。

代码如下:

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

希望对您有所帮助。

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