Vue.js Axios 响应类型 blob 或 json 对象

Vue.js Axios responseType blob or json object

我有一个 Axios 请求下载 .xls 文件。问题是 returned 作为来自后端的响应的对象并不总是必须是真实文件。如果我 return 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 => {
  })
}

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

所以问题是每个 returned 响应都变成了 blob 类型,而我在其中看不到我的 returned 数据。有什么想法吗?

我通过读取 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 => {
  })

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

看起来还是太老套了。

您是否尝试检查 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
  });
}

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