download属性仅对同源URL或blob:/data: URL生效,跨域时被忽略;必须配合有效href,空href或javascript:协议无效;服务端Content-Disposition响应头更可靠,跨域下载需fetch+Blob方案。

download属性只对同源URL生效
给 <a> 标签加了 download 却打开 PDF 而非下载,大概率是因为 href 指向了跨域地址。浏览器明确限制该属性仅在同源(协议、域名、端口完全一致)或 blob:/data: URL 下起作用。
常见误判场景:
-
<a href="https://cdn.example.com/report.pdf" download>下载</a>→ 跨域,download被忽略,PDF 在新标签页打开 -
<a href="./files/data.csv" download>下载</a>→ 同源静态文件,正常触发下载 - 本地双击 HTML 文件(
file://协议)→ 所有相对路径也被视为跨源,download必然失效
href缺失或无效导致点击无响应
download 不是独立开关,它必须依附于一个有效的 href。没有 href 或值为空字符串时,点击不会触发任何行为(包括导航和下载)。
容易踩的坑:
立即学习“前端免费学习笔记(深入)”;
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
<a download="log.txt">下载</a>→ 缺少href,点击无反应 -
<a href="" download="log.txt">下载</a>→href=""是空链接,部分浏览器会刷新页面 -
<a href="javascript:void(0)" download="log.txt">下载</a>→javascript:协议不支持download,直接被忽略 - 正确写法:
<a href="/api/export?format=csv" download="export.csv">下载</a>,但注意:这个接口必须同源,否则仍会跳转而非下载
服务端响应头比download更可靠
当后端能配合时,Content-Disposition: attachment; filename="xxx" 响应头比前端 download 属性更底层、更稳定——它绕过同源限制,无论链接是否跨域、是否用 <a>,浏览器都会弹出保存对话框。
关键点:
- 前端只需普通链接:
<a href="/api/export">导出</a>,无需download属性 - Node.js Express 可用
res.download(path)或手动设头:res.set('Content-Disposition', 'attachment; filename="report.pdf"') - Nginx 静态文件可配
add_header Content-Disposition "attachment";,但无法动态指定文件名 - 若服务端返回的是
text/plain或application/json等可预览类型,即使有download,浏览器也可能优先渲染;而Content-Disposition会强制覆盖该行为
跨域下载必须用 fetch + Blob 方案
面对 CDN 文件、第三方 API 或无法修改响应头的后端,唯一可行的前端方案是:用 fetch 获取二进制流 → 转为 Blob → 创建 blob: URL → 绑定 download → 触发点击。
实操要点:
- 目标资源需支持 CORS(响应头含
Access-Control-Allow-Origin),否则fetch直接失败 - 必须在用户手势事件内调用
click()(如button.onclick),不能放在setTimeout或异步回调末尾,否则被浏览器拦截 -
a.href必须在a.download之后设置,Safari 对顺序敏感 - 别漏掉
URL.revokeObjectURL(url),否则内存泄漏 - 示例核心逻辑:
const a = document.createElement('a');<br>a.href = URL.createObjectURL(blob);<br>a.download = 'data.json';<br>document.body.appendChild(a);<br>a.click();<br>document.body.removeChild(a);<br>URL.revokeObjectURL(a.href);
真正容易被忽略的是:同源判断不仅看域名,还卡协议和端口;file:// 下所有操作都默认失效;而服务端响应头才是下载控制的“最终解释权”所在——前端 download 只是个弱提示,别把它当开关用。


















