在前端开发中,实现文件下载是常见的需求。根据不同的场景,我们可以选择不同的方法来实现文件流的下载。本文介绍三种常用的文件下载方式:
axios
发送 JSON 请求下载文件流axios
发送 FormData
请求下载文件流form
表单提交下载文件流适用于需要通过 POST 请求发送 JSON 数据给后端以获取文件流的情况。
responseType: 'blob'
。Blob
对象处理响应数据。Content-Disposition
头部字段,部分浏览器可能不支持,需服务器配置允许跨域访问该头部。axios({
url: 'https://localhost/download/test',
method: 'post',
data: {
headers: ["姓名", "年龄", "城市"],
data: [{
"姓名": "张三",
"年龄": 25,
"城市": "北京"
}],
fileName: "99"
},
responseType: 'blob',
withCredentials: true
}).then(response => {
// 获取文件名
let filename = '默认文件.xlsx';
const disposition = response.headers['content-disposition'];
if (disposition && disposition.indexOf('filename=') !== -1) {
filename = disposition.split('filename=')[1].replace(/"/g, '');
try {
filename = decodeURIComponent(filename);
} catch (e) {
filename = unescape(filename);
}
}
// 创建 Blob 并触发下载
const blob = new Blob([response.data], { type: response.headers['content-type'] });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(link);
});
适用于需要传递键值对形式的数据(如上传文件)或模拟表单提交的场景。
'application/x-www-form-urlencoded'
。FormData
构造请求体。const formData = new FormData();
formData.append("key", "value");
axios({
url: 'http://localhost/api/download',
method: 'post',
data: formData,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
responseType: 'blob',
withCredentials: true
}).then(response => {
const disposition = response.headers['content-disposition'];
let filename = '默认文件.xlsx';
if (disposition && disposition.includes('filename=')) {
filename = disposition.split('filename=')[1].replace(/"/g, '');
try {
filename = decodeURIComponent(filename);
} catch (e) {
filename = unescape(filename);
}
}
const blob = new Blob([response.data], { type: response.headers['content-type'] });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(link);
});
适用于不需要 JavaScript 控制、直接通过表单提交参数并由后端返回文件流的场景。
元素。const paraData = { id: 1212, name: '测试名' };
const formActionUrl = gateUrl + '/api/dictData/downloadDictDataList';
const form = document.createElement('form');
form.style.display = 'none';
form.action = formActionUrl;
form.method = 'post';
form.enctype = 'application/x-www-form-urlencoded'; // 可选
document.body.appendChild(form);
for (let key in paraData) {
if (paraData.hasOwnProperty(key)) {
const input = document.createElement('input');
input.type = 'hidden';
input.name = key;
input.value = paraData[key];
form.appendChild(input);
}
}
form.submit(); // 提交表单
form.remove(); // 移除表单
方法 | 是否支持 JSON | 是否支持文件下载 | 是否支持动态文件名 | 是否异步 | 是否推荐 |
---|---|---|---|---|---|
Axios + JSON | ✅ | ✅ | ✅(依赖响应头) | ✅ | ✅ 推荐 |
Axios + FormData | ❌(自动转换) | ✅ | ✅ | ✅ | ✅ 推荐 |
原生 Form | ❌ | ✅ | ❌ | ❌ | ⚠️ 视情况 |