download 属性仅在同源静态路径、blob url 或短 data url 三种场景下生效,跨域、file:// 协议、safari 浏览器及 content-disposition: inline 均使其失效;真正决定下载的是服务端响应头。

download 属性不是“强制下载开关”,它只是在满足严格前提时才生效的提示信号。不满足条件时,浏览器会直接忽略它,点击后该跳转还跳转、该预览仍预览。
为什么加了 download 却没反应?
最常见原因是链接跨域——哪怕只是 CDN 域名和主站域名不同(如 https://yoursite.com 页面里写了 href="https://cdn.yoursite.com/file.pdf"),浏览器就认为不是同源,download 被静默丢弃。
- 检查控制台是否有
download attribute has no effect on cross-origin links警告 - 本地用
file://协议打开 HTML 时,download全部失效,必须起本地服务(如npx serve) - Safari 全系(包括 iOS/iPadOS)完全不支持
download,点同源链接也会打开预览 - 服务器返回了
Content-Disposition: inline响应头,会覆盖download行为
download 的合法使用场景有哪些?
只有三类链接能真正触发 download:
- 同源静态路径:
/assets/report.xlsx、./data.json、https://yoursite.com/files/manual.pdf(协议、域名、端口必须完全一致) -
blob:URL:由URL.createObjectURL(blob)动态生成,此时download值是唯一决定保存名的方式 - 短
data:URL(如 base64 图片):部分浏览器支持,但 Safari 不认,且长内容易截断或失败
注意:download="path/to/name.pdf" 中的斜杠会被浏览器忽略,最终只取 name.pdf;含非法字符(/、\、:)会导致整个属性失效。
跨域文件怎么真正下载下来?
靠前端加 download 属性没用,得绕过浏览器限制:
- 服务端加响应头:
Content-Disposition: attachment; filename="export.csv"—— 这是最可靠方式,无论是否跨域、是否用<a></a>标签,都会触发下载 - 前端 fetch + Blob:
fetch()请求资源(需目标服务返回Access-Control-Allow-Origin),调用response.blob(),再用URL.createObjectURL()创建临时链接并.click() - 后端代理中转:前端请求自己的接口(如
/api/proxy?url=https%3A%2F%2Fremote.com%2Ffile.zip),由后端发起真实请求并透传响应头
别写 <a href="xxx" target="_blank" download></a> —— target="_blank" 会干扰下载行为,导致点击后新开标签页而非下载。
最容易被忽略的关键点
不是前端代码写得不够多,而是服务端配置漏了。哪怕 <a download="report.pdf" href="/files/report.pdf"></a> 写得再标准,如果 Nginx 没配 add_header Content-Disposition "attachment";,或者 Express 没调用 res.download() 或手动设头,Chrome 可能仍打开 PDF,Safari 则根本不会下载。真正的控制权在响应头上,不在 HTML 属性里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











