download属性仅对同源URL生效,跨域、Data URL或旧浏览器中会失效;建议显式指定安全文件名,并通过服务端设置Content-Disposition和CORS头来增强兼容性。

download 属性只对同源 URL 生效
浏览器出于安全限制,download 属性仅在链接指向**同源资源**(即协议、域名、端口完全一致)时才真正触发下载;否则会直接跳转或打开,不会下载。这是最常被忽略的前提,很多开发者本地测试时用 file:// 协议,或链接到 CDN 上的图片/CSS/JS 文件,download 都会被静默忽略。
验证方式很简单:右键点击带 download 的链接 → “检查” → 查看控制台是否出现类似 Download is only permitted for same-origin URLs 的警告。
- ✅ 正确示例:
<a href="/assets/report.pdf" download="monthly-report.pdf">下载报表</a> - ❌ 无效示例:
<a href="https://cdn.example.com/data.csv" download>下载数据</a>(跨域,不下载) - ❌ 无效示例:
<a href="data:text/plain,hello" download>下载文本</a>(Data URL,多数浏览器不支持download)
download 属性值不是必须的,但建议显式指定文件名
download 是布尔属性,写成 download 或 download="" 都表示启用下载行为;但若提供值(如 download="invoice.pdf"),浏览器会优先使用该值作为保存的默认文件名——这对用户友好,也避免后端返回的原始文件名含特殊字符或不直观。
注意:这个值**不经过路径解析**,不能包含 /、../ 等路径字符,否则整个属性会被浏览器忽略(部分浏览器会降级为无 download 行为)。
立即学习“前端免费学习笔记(深入)”;
- ✅ 安全写法:
<a href="receipt.json" download="2024-06-receipt.json">下载凭证</a> - ❌ 危险写法:
<a href="log.txt" download="../etc/passwd">下载日志</a>(会被忽略,且有安全误导风险) - ⚠️ 注意:如果服务器响应头中设置了
Content-Disposition: attachment; filename="server-name.xlsx",部分浏览器会优先采用响应头里的文件名,覆盖download值
不支持 download 的 fallback 方案怎么补
当目标资源跨域、是 Data URL、或运行在不支持 download 的旧浏览器(如 IE、iOS Safari ≤12.5)时,<a download> 会退化为普通链接。你需要主动检测并提供替代逻辑。
简单可靠的 fallback 是用 JavaScript 触发 Blob 下载:
function downloadFromUrl(url, filename) {
fetch(url)
.then(r => r.blob())
.then(blob => {
const a = document.createElement('a');
const urlObj = URL.createObjectURL(blob);
a.href = urlObj;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(urlObj);
});
}
- 该方案绕过同源限制(只要 API 允许 CORS)
- 注意:大文件(>500MB)可能触发内存压力,不建议无脑用此方式下载
- iOS Safari 对
createObjectURL+a.click()支持不稳定,部分版本需用户手动长按“保存到文件”
服务端配合能解决 80% 的 download 失效问题
与其前端硬扛跨域和兼容性,不如让服务端主动支持下载语义。关键就两点:
- 确保响应头包含
Content-Disposition: attachment; filename="xxx.ext" - 确保响应头包含
Access-Control-Allow-Origin: *(或具体域名)+Access-Control-Allow-Headers: Range(如需支持断点续传) - 避免设置
Cache-Control: no-store以外的强缓存策略,否则 Safari 可能拒绝触发下载
例如 Nginx 配置静态下载路径:
location /downloads/ {
add_header Content-Disposition "attachment";
add_header Access-Control-Allow-Origin "*";
}
这样前端就可以放心用 <a href="/downloads/config.zip" download>下载配置</a>,无需 JS 干预。
真正难搞的是那些你无法控制响应头的第三方资源——这时候别硬刚 download,老实用 fetch + Blob + 用户引导更稳妥。



















