文件下载方法+踩坑实录
文件下载思路:后端传给前端一个二进制流文件,前端将它封装成blob类型,然后调用接口进行文件下载。
接口配置(踩坑)
首先要知道post后面第一个参数是url,第二个参数是body,第三个参数是config
我们使用axios
进行接口的封装(如何封装这里就不说了,有需要的可以联系博主)
对于下载功能的接口,电子所的项目是这样的:
(因为后端的要求所以把dataId,productType拼接到url中调用接口。实际情况还是要根据自己的项目实际来配置接口)
可以看到在url后面有一个空的 {},这个空的{}非常的关键!!!。
因为我们是使用blob的方式调用接口获得路径然后下载,所以需要在接口处添加responseType: 'blob'
,不然下载的文件会出现损坏。
并且(划重点),如果你把空的{}去掉了,你下载的文件也会出现损坏,因为axios会默认把{responseType: ‘blob’}当成request body进行封装,而不是config。very important!!!
getDetailDownload(dataId, productType){
return http.post(`/retrieval/system/data/download/?dataId=${dataId}&productType=${productType}`, {},
{responseType: 'blob'});
},
File-Saver文件下载
先给个file-saver的文档:戳这里
安装File-saver
npm命令安装:npm install file-saver -s
在需要的module中引入:import saveAs from 'file-saver';
File-saver的使用
detailDownload(detail) {
apiService.getDetailDownload(detail.id, detail.productType)
.then((href) => {
const blob = new Blob([href.data], {type: href.header['content-type']});
const fileName = href.header['content-disposition'].split(";")[1].split("filename=")[1];
saveAs(blob, fileName);
}).catch(() => {
});
},
//因为需要拿到文件名字,和后端商量好将文件名放在content-disposition暴露给前端
就是这么简单!
通过a标签进行文件下载
原理也是封装blob类型对象。调用URL.createObjectURL
方法生成a标签的url实现点击a标签进行下载
detailDownload(detail) {
apiService.getDetailDownload(detail.id, detail.productType)
.then((href) => {
const blob = new Blob([href.data], {type: href.header['content-type']});
const fileName = href.header['content-disposition'].split(";")[1].split("filename=")[1];
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.download = fileName;
link.href = url;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}).catch(() => {
});
},
一对比就能感觉到file-saver更好用嘛!