我有一个 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 类型,并且我在其中看不到返回的数据。有任何想法吗?
您尝试过检查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 响应仍然是文本响应,但处理方式略有不同。
我通过读取 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
看起来还是太老套了。