download属性仅对同源url生效;跨域需用blob+createobjecturl并调用click()触发,注意释放url、处理mime类型;同源无文件名路径时download仍有效,但受content-disposition响应头优先级影响;ios safari完全不支持download属性。

download 属性只对同源 URL 生效
直接给 <a></a> 标签加 download="xxx.jpg" 不一定起作用——浏览器会检查 href 是否为同源地址(协议、域名、端口全一致)。跨域链接(比如指向 https://cdn.example.com/img.png)即使写了 download,点击后也会打开新页面或触发浏览器默认下载行为,且文件名由响应头 Content-Disposition 或 URL 路径决定,download 属性被忽略。
想改跨域资源的下载名?得用 Blob + URL.createObjectURL
这是目前最可靠的方式:先用 fetch 获取资源,转成 Blob,再生成本地 blob URL,最后绑定到 <a download="xxx"></a>。注意必须调用 a.click() 触发下载,不能靠用户手动点击(否则 blob URL 可能已失效)。
常见错误包括:
- 没设置
response.blob(),直接用response.text()导致二进制损坏 - 忘记调用
URL.revokeObjectURL(url),长期驻留内存(尤其在循环下载时) - 没处理 MIME 类型,导致 PDF/Excel 等文件打开异常(建议从
response.headers.get('content-type')读取, fallback 到application/octet-stream)
示例关键片段:
const link = document.createElement('a');
fetch('https://cdn.example.com/report.pdf')
.then(r => r.blob())
.then(blob => {
const url = URL.createObjectURL(new Blob([blob], { type: blob.type }));
link.href = url;
link.download = '2024年度报表.pdf';
link.click();
URL.revokeObjectURL(url); // 用完立即释放
});
同源但路径不带文件名?download 仍可覆盖
比如 href="/api/export?id=123" 这种后端接口地址,只要同源,download="data.csv" 就能生效——浏览器不会看 URL 路径,只认 download 属性值。前提是后端响应头里不要设 Content-Disposition: attachment; filename="xxx",否则它优先级更高,会覆盖 download 属性。
验证方法:打开 DevTools → Network → 找到该请求 → 查看 Response Headers 中是否有 Content-Disposition。有就让后端去掉,或改成 inline。
移动端 Safari 对 download 属性基本不支持
iOS/iPadOS 的 Safari 完全忽略 download 属性,无论同源与否。点击后一律打开预览或调用系统分享面板。此时唯一可行方案是服务端直出正确文件名:确保响应头包含 Content-Disposition: attachment; filename="xxx.xlsx",且 filename*(RFC 5987 编码)也提供,用于兼容特殊字符。
如果必须前端控制,只能降级提示用户“长按链接 → ‘下载链接’”(部分 iOS 版本支持),但体验差、不可靠。
别指望 fetch + Blob 在 iOS Safari 自动触发下载——它不支持 a.click() 下载 blob URL,只会静默失败或报错 NotAllowedError。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











