Vue.js Axios responseType blob 或 json 对象

The*_*e50 2 blob vue.js axios

我有一个 Axios 请求下载 .xls 文件。问题是作为后端响应返回的对象并不总是必须是真实文件。如果我返回 json 对象而不是文件数据。那我该如何读取这个json呢?

这是函数:

downloadReport() {
  let postConfig = {
    headers: {
      'X-Requested-With': 'XMLHttpRequest'
    },
    responseType: 'blob',
  } as AxiosRequestConfig

  axios
  .post(this.urls.exportDiscountReport, this.discount.id, postConfig)
  .then((response) => {
    let blob = new Blob([response.data], { type: 'application/vnd.ms-excel' });
    let url = window['URL'].createObjectURL(blob);
    let a = document.createElement('a');
    a.href = url;
    a.download = this.discount.id + ' discount draft.xlsx';
    a.click();
    window['URL'].revokeObjectURL(url);
  })
  .catch(error => {
  })
}
Run Code Online (Sandbox Code Playgroud)

我想读取响应,如果它包含一些数据 - 不要创建 blob 并启动下载,而是仅显示一些消息或其他内容。如果我删除 responseType: 'blob' 则 .xls 文件将下载为不可读且无效的文件。

所以问题是每个返回的响应都会变成 blob 类型,并且我在其中看不到返回的数据。有任何想法吗?

Ale*_*abe 6

您尝试过检查responseBlob.type房产吗?它给出了返回数据的 MIME 类型。

例如,你可以有这样的东西:

const jsonMimeType = 'application/json';
const dataType = responseBlob.type;

// The instanceof Blob check here is redundant, however it's worth making sure
const isBlob = responseBlob instanceof Blob && dataType !== jsonMimeType;

if (isBlob) {

  // do your blob download handling

} else {
  responseBlob.text().then(text => {
    const res = JSON.parse(text);
    // do your JSON handling
  });
}
Run Code Online (Sandbox Code Playgroud)

我发现这更简单并且对我有用,但这取决于您的后端设置。BLOB 响应仍然是文本响应,但处理方式略有不同。


The*_*e50 5

我通过读取 blob 响应并检查它是否具有 JSON 参数状态来解决这个问题。但这对我来说似乎是过度设计。有更好的解决方案吗?

let postConfig = {
  headers: {
    'X-Requested-With': 'XMLHttpRequest'
  },
  responseType: 'blob',
} as AxiosRequestConfig

axios
  .post(this.urls.exportDiscountReport, this.discount.id, postConfig)
  .then((responseBlob) => {
    const self = this;
    let reader = new FileReader();

    reader.onload = function() {
      let response = { status: true, message: '' };

      try {
        response = JSON.parse(<string>reader.result);
      } catch (e) {}

      if (response.status) {
        let blob = new Blob([responseBlob.data], { type: 'application/vnd.ms-excel' });
        let url = window['URL'].createObjectURL(blob);
        let a = document.createElement('a');
        a.href = url;
        a.download = self.discount.id + ' discount draft.xlsx';
        a.click();
        window['URL'].revokeObjectURL(url);
      } else {
        alert(response.message)
      }
    }
    reader.readAsText(responseBlob.data);
  })
  .catch(error => {
  })
Run Code Online (Sandbox Code Playgroud)

我在这里也找到了相同的解决方案: https: //github.com/axios/axios/issues/815#issuecomment-340972365

看起来还是太老套了。