
一、最常见方式:a
标签 + Blob
如果后端返回的是二进制数据(Blob / ArrayBuffer),我们可以把它转成 Blob
对象,然后用 URL.createObjectURL
生成下载链接。
fetch('/api/download/file', {
method: 'GET',
headers: {
// 如果需要携带 token 之类的,可以加上
'Authorization': 'Bearer xxx'
}
})
.then(res => res.blob()) // 转换为 blob
.then(blob => {
const url = window.URL.createObjectURL(blob); // 创建临时链接
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'myFile.zip'; // 下载文件名(可根据后端返回动态设置)
document.body.appendChild(a);
a.click(); // 触发下载
document.body.removeChild(a);
window.URL.revokeObjectURL(url); // 释放内存
});
👉 注意:
-
a.download
属性设置文件名,如果不写,可能会用 URL 里的名字。 -
window.URL.revokeObjectURL(url)
用于释放临时对象,避免内存泄露。
二、获取文件名(Content-Disposition)
有些后端会在响应头里加 Content-Disposition: attachment; filename="xxx.pdf"
,这时候可以动态解析文件名。
fetch('/api/download/file')
.then(async res => {
const blob = await res.blob();
const disposition = res.headers.get('Content-Disposition');
let filename = 'default.file';
if (disposition && disposition.includes('filename=')) {
filename = decodeURIComponent(
disposition.split('filename=')[1].replace(/"/g, '')
);
}
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
});
三、使用 axios
下载二进制文件
如果用 axios,要记得设置 responseType: 'blob'
:
import axios from 'axios';
axios.get('/api/download/file', {
responseType: 'blob'
}).then(res => {
const blob = new Blob([res.data]);
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'download.zip';
a.click();
window.URL.revokeObjectURL(url);
});
四、兼容 IE 的方案(msSaveBlob)
旧版 IE/Edge 不支持 URL.createObjectURL
,需要用 msSaveOrOpenBlob
:
if (window.navigator.msSaveOrOpenBlob) {
// IE/Edge 专用
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
// 现代浏览器
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
}
五、后端直接返回下载链接(非二进制流)
如果后端直接返回一个下载 URL(不是流),最简单的就是:
window.location.href = '/api/download/file';
但缺点是:
-
不好控制文件名
-
不方便带自定义 header(如 token)
✅ 总结:
-
如果后端返回二进制流 →
fetch/axios + blob + a.download
-
如果后端返回
Content-Disposition
→ 解析文件名 -
兼容老浏览器(IE/Edge) →
msSaveOrOpenBlob
-
如果只是个直链 →
window.location.href