前端选择使用哪种方式来进行下载动作,需要和后端进行协商。
- 如果后端接口直接返回下载文件,那么前端就使用get请求url的方式进行下载
- 如果后端接口返回的是Blob文件流,那么前端就使用ajax进行请求得到响应Blob数据进行处理后下载
- 模拟form表单提交进行下载(实际开发一般不用)
1、后端接口直接返回下载文件
const downloadDialogue = (url, params) => {
let result = '';
// 参数拼接
Object.keys(params).forEach((item) => {
result += `${item}=${params[item]}&`;
});
const param = result.slice(0, result.length - 1);
const urls = `${url}?${param}`;
// 打开浏览器窗口即为get请求,浏览器自动触发下载动作
window.open(urls);
// 下面这个方式也可以,但是没有打开新窗口的视觉感,网络不好的时候还以为点击失效
// const a = document.createElement('a');
// a.href = urls;
// document.body.appendChild(a);
// a.click();
// window.URL.revokeObjectURL(urls);
// document.body.removeChild(a);
};
// 请求接口逻辑
downloadDialogue(
// 下载url
`xxx.xxx.exportList`,
// 下载传给后台的参数
{
// 下载需要的参数
}
);
2、后端接口返回的是Blob文件流
// response 就是后端接口返回的Blob文件流
const downloadFile = (response) => {
if (!response) {
return;
}
const blob = new Blob([response.data]);
let fileName;
const disposition = response.headers && response.headers['content-disposition'];
if (!disposition) {
message.error('文件名缺失');
fileName = '下载文件.xls';
} else {
fileName = disposition.split('filename=')[1];
fileName = decodeURIComponent(fileName) || fileName; // 中文处理
}
if ('download' in document.createElement('a')) {
// 非IE下载
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
} else {
navigator.msSaveBlob(blob, fileName);
}
};
// 请求接口逻辑(这里使用axios举例)
axios.post(
// 下载url
`xxx/xxx/export`,
// 传给后台的参数
{
// 下载需要的参数
},
// 返回格式为Blob文件流,需要添加这个参数
{
responseType: 'blob',
},
).then((res) => {
// 调用下载函数
downloadFile(res);
}).catch((err) => {
console.log(err);
});