download 属性仅对同源 URL 有效,跨域、file:// 协议或 Content-Disposition: inline 响应头均会导致其失效;正确用法限于同域静态资源、Blob 或 data URL(部分浏览器支持),跨域时需服务端配合或前端生成 Blob 下载。

download 属性本身不能“实现下载链接”,它只是告诉浏览器:这个 <a> 链接点击后应触发下载行为,而非跳转或打开。但它的生效有严格限制——不是加了就管用。
为什么加了 download 却没反应?
浏览器只允许对同源(same-origin)URL 使用 download。也就是说,如果你的 HTML 页面在 https://example.com,而链接指向 https://cdn.example.com/file.pdf(即使域名属于你),只要协议、端口、主机名不完全一致,download 就会被忽略,浏览器退化为普通跳转或新开标签页。
- 常见错误现象:
<a href="https://oss.aliyuncs.com/xxx.zip" download="report.zip">下载</a>点击后直接在新标签打开 ZIP,不下载 - 本地文件测试也无效:用
file://协议打开 HTML 时,所有download都被禁用(Chrome/Firefox 均如此) - 服务器返回的响应头若含
Content-Disposition: inline,也可能覆盖download行为
download 的正确使用场景和写法
它只适用于你完全控制资源 URL 的情况,比如前端生成的 Blob、base64 数据 URL,或同域下的静态文件路径。
- 同域静态文件(推荐最简方案):
<a href="/assets/data.csv" download="export.csv">导出 CSV</a>—— 路径必须是相对路径或同源绝对路径 - Blob 对象(最常用且可控):用
URL.createObjectURL(blob)创建临时 URL,再赋给<a>的href,此时download必定生效 - 不要对 base64 URL 依赖
download:虽然部分浏览器支持,但 Safari 完全不认data:text/plain;base64,...+download的组合
替代方案:当 download 不可用时怎么办
遇到跨域、file:// 或需要兼容老浏览器时,得绕过 download 属性本身。
- 服务端配合:让后端在响应头中明确设置
Content-Disposition: attachment; filename="xxx.pdf",前端用window.open(url)或<iframe src="url">触发(注意 CORS 和弹窗拦截) - 前端生成并下载 Blob:这是目前最可靠的方式,不依赖同源,也不需要后端改头。
fetch拿到二进制数据 →new Blob([res.arrayBuffer()])→URL.createObjectURL()→ 创建<a>并.click() - 避免用
location.href = url试图触发下载:它无法指定文件名,且在多数现代浏览器中会失效
真正难的不是写 download 这个属性,而是判断当前链接是否满足它的运行前提。很多问题本质是跨域策略或协议限制,而不是代码漏写了什么。别急着查“怎么用”,先看控制台 Network 面板里那个请求的 Referrer Policy 和 Response Headers 是什么。

















