download属性仅对同源url生效,跨域需用fetch+blob方案;同源指协议、域名、端口全一致;data:和blob: url可下载但有兼容性限制;服务端须设置content-disposition响应头。

download 属性只对同源 URL 生效
直接给 @#@#@#@#@#@#@#@#@#@0 和 @#@#@#@#@#@#@#@#@#@1 效果一致:浏览器会尝试从 href 的 URL 路径中提取文件名(如 https://x.com/a/b/c.pdf → c.pdf)。但若 URL 是纯路径无扩展名(如 /api/download?id=123),则可能保存为无后缀的乱码文件或默认叫 download。
- 显式写
download="invoice-2024.pdf"是最稳妥的做法,能控制最终保存名 - 注意:文件名中不要含
/、\、:等非法字符,否则部分浏览器会截断或报错 - Safari 对
download支持较弱(尤其 iOS),即使同源也可能拒绝下载,需降级为新开窗口 + 提示用户右键另存
服务端需配合的细节容易被忽略
前端加了 download,不代表一定能下。服务端响应头必须配合,否则浏览器可能按 MIME 类型决定是下载还是渲染。
- 关键响应头:
Content-Disposition: attachment; filename="xxx.pdf"(强制下载) - 避免返回
Content-Type: text/html或application/json,即使文件是 PDF;应返回真实类型,如application/pdf、text/csv - 如果接口需要鉴权(如带 Cookie 或 Bearer Token),
fetch必须加credentials: 'include'或headers: { Authorization: '...' },否则 401 - 大文件下载时,服务端别超时,前端也建议加 loading 状态,避免用户重复点击生成多个
blob:URL
真正卡住的往往不是 download 属性本身,而是同源限制、响应头缺失、Blob 处理不当这三点中的某一个。先检查 Network 面板里请求是否成功、响应头是否含 Content-Disposition、控制台有无 CORS 报错,比反复改 HTML 更有效。
fetch('/api/export?format=csv')
.then(res => res.blob())
.then(blob => {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'report.csv'; // 手动指定,或从 header 解析
a.click();
URL.revokeObjectURL(url); // 用完立即释放,避免内存泄漏
});前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











