download属性仅对同源链接生效,跨域、file://协议、iOS Safari均不支持,动态接口需用Blob+URL.createObjectURL方案实现下载。

download 属性只对同源链接生效
download 属性看起来很直接:加在 <a> 上,点一下就下载。但实际用的时候,如果链接指向的是跨域资源(比如 CDN 上的 PDF、远程 API 返回的文件 URL),浏览器会直接忽略 download,转而跳转或打开——根本不会触发下载。
- 同源是硬性前提:链接的
origin(协议 + 域名 + 端口)必须和当前页面一致 - 常见踩坑:本地双击 HTML 文件(
file://协议)时,所有download都失效,连同源都算不上 - 替代方案不是加个
target="_blank"就行,那只是新开页,不等于下载
表格里放下载链接,href 必须指向真实文件路径
在 <table> 里写 <a download="report.pdf" href="data/reports/report.pdf">下载报表</a> 是可行的,但要注意:
-
href不能是后端接口地址(如/api/export?format=csv),除非该接口返回明确的Content-Disposition: attachment响应头,否则download属性无效 - 如果文件路径是相对的,确保路径相对于当前 HTML 文件位置正确;用绝对路径(如
/static/files/xxx.xlsx)更稳 - 不要用 JavaScript 拼接
href后再设置download,动态生成的 URL 若非同源,照样被忽略
想下载接口返回的内容?得靠 Blob + URL.createObjectURL
当文件由后端 API 动态生成(比如导出 Excel),<a download> 没法直接用。必须走 JS:
- 先用
fetch请求接口,得到Response.blob() - 创建临时 URL:
const url = URL.createObjectURL(blob) - 创建隐藏
<a>标签,设置href和download,然后.click() - 最后记得调用
URL.revokeObjectURL(url)防内存泄漏
示例关键片段:
使用 Puppeteer + Chrome 将 HTML 渲染为中文 PDF,自动处理图表等待、Tab 展开、动画、测高、白边消除、防分页,适用于看板、报表、网页和交互图表转 PDF。
立即学习“前端免费学习笔记(深入)”;
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 = 'export.csv';
a.click();
URL.revokeObjectURL(url);
});移动端 Safari 对 download 属性支持极差
iOS Safari 完全不支持 download 属性,无论同源与否。点链接只会尝试打开(PDF 可能预览,Excel 直接失败)。没有警告,也不报错,就是“没反应”。
- 别依赖它做 iOS 下载逻辑
- 要兼容,要么服务端加
Content-Disposition强制附件响应,要么前端用 Blob 方案(iOS Safari 支持URL.createObjectURL和<a>.click()) - 表格中可加提示文字,比如
<span style="font-size:0.8em;color:#666">(iOS 用户请长按链接另存)</span>,虽然体验打折,但比完全不可用强
真正卡住人的地方,往往不是怎么写,而是没意识到 download 的限制比文档写的还严——它既认协议,又认环境,还分设备。写完记得在 Chrome、Firefox、Safari(桌面+iOS)、Edge 都点一遍试试。


















