使用axios下载后端返回的文件流,并能够提示后端报错信息
这里与后端已经约定好了,成功有文件流时返回staus为0
问题:当下载文件时,axios配置responseType: ‘blob’,此时后台返回的数据会被强制转为blob类型;如果后台返回失败对象,前端也无法得知,如果按正常处理会得到名为undefined的文件。
解决:在try代码块里面尝试将axios已经转成blob格式的res转回json格式,如果不报错说明服务端返回的是对象,表示下载失败,提示出后端返回的错误;如果进入catch说明返回的是二进制流。
具体代码如下(这里的提示使用的是elementUI提供的message,下载的文件是压缩包文件,也可以根据需求修改文件类型):
// 点击下载事件 async downloadFile() {var that = this; axios({ method: 'post', url: '', data: this.searchForm, responseType: 'blob', }) .then((res) => { const data = res.data; // 有可能下载失败,比如返回{status: 0},但设置了responseType: 'blob',axios会把data强制转为blob,导致下载undefined.excel(后缀取决于文件类型,这里只是举例) // 解决:将已转为blob类型的data转回json格式,判断是否下载成功 const r = new FileReader(); r.onload = function () { // 如果JSON.parse(this.result)不报错,说明this.result是json字符串,则可以推测是下载报错情况下返回的对象,类似于{status: 0} // 如果JSON.parse(this.result)报错,说明是下载成功,返回的二进制流,则进入catch进行后续处理 try { const resData = JSON.parse(this.result); // this.result为FileReader获取blob数据转换为json后的数据,即后台返回的原始数据 // 如果执行到这里,说明下载报错了,进行后续处理 if(resData.status !== 0) { that.$message({ message: resData.statusText, type: 'warning', }); } } catch (err) { // 下载正常处理 that.$message({ message: '文件下载中', type: 'success', }); let blob = new Blob([res.data], { type: 'application/zip' }); //如果文件是excel,把type换成 type: 'application/vnd.ms-excel' 即可
let url = window.URL.createObjectURL(blob); const link = document.createElement('a'); // 创建a标签 link.href = url; link.download = '文件名'; // 重命名文件 link.click(); URL.revokeObjectURL(url); // 释放内存 } }; r.readAsText(data); // FileReader的API }) .catch((res) => { console.log(res); that.$message.error('下载失败'); }); },
这样就可以啦!