后台接口返回二进制文件流,前端通过blob对象并使用fetch/axios实现下载excel
使用场景:我们在项目中实现文件下载的方法有多种,一般都是接口返回url或者get请求访问接口直接下载。但是有时项目会要求在发送请求的时候加上token验证,这时如果直接访问接口会有权限限制访问失败,因此需要通过以下请求的方式接受后台返回的二进制文件流,此时在查看或者打印返回的内容时,会发现都是乱码,因此需要通过blob对象来接收返回的二进制文件流并转化为文件地址,但有时也会经常出错,下载成功打开文件还是乱码,下面通过fetch/axios实现下载过程会出现的问题总结了几点注意事项和配置。
axios
download() {
const data = { }// 要发送到后台的数据
axios({
method: 'get',
url: '/downFile/file', // 请求地址
data: data, // 参数
responseType: 'blob' // 表明返回服务器返回的数据类型 这里注意要加上responseType
})
.then((res) => { // 处理返回的文件流
// 注意 返回的res 无需做任何处理,有时在用框架封装的请求之后会出现返回response.text() 等情况导致文件流下载失败。
const blob = new Blob([content])
const fileName = 'down.xls'
const alink = document.createElement('a')
alink.download = fileName
alink.style.display = 'none'
alink.href = URL.createObjectURL(blob) // 这里是将文件流转化为一个文件地址
document.body.appendChild(alink)
alink.click()
URL.revokeObjectURL(alink.href) // 释放URL 对象
document.body.removeChild(alink)
})
}
fetch
简要摘一段项目代码介绍
fetch(url).then(res => res.blob().then(blob => {
// 这里是将res.blob() 方式处理文件流,之前我采取了上述axios的书写方式一直未成功,后采取了 直接将 res.blob() 返回则下载成功,大家可以尝试一下。
var alink= document.createElement('a');
alink.style.display = 'none'
alink.href = window.URL.createObjectURL(blob);
alink.download = res.headers.get('Content-Disposition'); // 设置文件名
document.body.appendChild(alink)
alink.click();
URL.revokeObjectURL(alink.href) // 释放URL 对象
document.body.removeChild(alink)
}));
注意:前端通过上述处理方式之后,还需注意服务器的响应头content-type的设置须为content-type:‘application/vnd.ms-excel’