在请求下载的时候,为了解决乱码问题,我们都会给 XHR 的 responseType 指定为 blob 或者 arraybuffer。但是在实际下载的过程中,后端返回的不一定是二进制流数据,也有可能是 json 格式的错误信息,比如导出数据量过大,需要缩小范围,或者查询结果出错等错误信息,需要在前端页面以 toast 的方式提示给使用者。
// 记住,这个地方传入的是response,而不是请求拿到的response.data
function judgeErrorByResponseType(response) {
return new Promise((resolve, reject) => {
if (response.headers['content-type'].includes('json')) {
// 此处拿到的data才是blob
const { data } = response
const reader = new FileReader()
reader.onload = () => {
const { result } = reader
const errorInfos = JSON.parse(result)
const { msg } = errorInfos
reject(new Error(msg))
}
reader.onerror = err => {
reject(err)
}
reader.readAsText(data)
} else {
resolve(response)
}
})
}
当然,我前端在这个方法的编写的时候对后台也是有要求的,就是要他准确的返回 content-type。如果是二进制流数据,content-type就必须是application/octet-stream,如果是 JSON 数据格式的错误信息,就必须得返回application/json。因为本次实践中我发现了后台有一些不规范的地方,就是不管返回的是什么数据类型,headers 永远是Content-Type: application/json;charset=UTF-8。