先看接口返回的数据长什么样子
就是这个丑样子
前端怎么处理呢?????????????????
前端正常拿一下 响应数据
可以看到data是二进制的流,这时候需要我们在请求的时候加上响应类型,将二进制的流转成 blob 格式,怎么转呢?加上下面这行代码
responseType: 'blob'
放到请求头中去,接下来我们再看返回的响应数据
这个时候返回的 data 是一个blob类型,而且 Size有大小 这就正常了,
如果返回的data 的 size 大小为0类似下面这样,可能就是项目中封装的 axios 有问题了,此时不妨在组件中单独引入 axios 去试一下。
如果还是不行,就用 postman 试一下看看能否正常下载,如果不能正常下载,那就是后台的锅,甩给他们就得了
如果一切都OK !!!
接下来就是解析响应数据,执行下载了
let blob = new Blob([data], { type: 'application/vnd.ms-excel;charset=utf-8' }) // 将服务端返回的文件流(二进制)excel文件转化为blob
let fileName = window.decodeURI(headers['content-disposition'].split('=')[1], "UTF-8");
完整的代码:
axios.post({
url: `/platform/push/downloadExcel/${row.id}`,
params: {},
responseType: "blob"
}).then(({ data, headers }) => {
let blob = new Blob([data], { type: 'application/vnd.ms-excel;charset=utf-8' }) // 将服务端返回的文件流(二进制)excel文件转化为blob
let fileName = window.decodeURI(headers['content-disposition'].split('=')[1], "UTF-8");
//浏览器兼容写法
if (window.navigator && window.navigator.msSaveOrOpenBlob) { // IE
window.navigator.msSaveOrOpenBlob(blob, fileName)
} else {
let objectUrl = (window.URL || window.webkitURL).createObjectURL(blob)
let downFile = document.createElement('a')
downFile.style.display = 'none'
downFile.href = objectUrl
downFile.download = fileName // 下载后文件名
document.body.appendChild(downFile)
downFile.click()
document.body.removeChild(downFile) // 下载完成移除元素
// window.location.href = objectUrl
window.URL.revokeObjectURL(objectUrl) // 只要映射存在,Blob就不能进行垃圾回收,因此一旦不再需要引用,就必须小心撤销URL,释放掉blob对象。
}
}).finally(() => {
this.loading = false;
})
补充更新:
因为文件下载responseType=blob,响应回来的不管是二进制流还是错误的json,都会包装成blob对象。可以尝试用FileReader去读响应回来的数据,读出来的数据JSON.parse一下,用try catch 包裹在外面,报错了就是文件流做下载处理,没报错就是json对象,弹框提示错误信息。