跳到正文
效率工具实用笔记关于本站
浏览器工具

超链接的 download 属性:下载文件时的限制

约 8 分钟阅读AI 辅助整理

download 属性只在同源 URL 或 blob:、data: 协议下生效,跨源链接会被忽略。文件名提示可能被 Content-Disposition 覆盖,浏览器行为也因设置而异。本文用自建文本样例说明这些限制。

本文要点

  1. download 属性可以带值,也可以不带值,两种写法对文件名的影响不同

  2. download 属性不是唯一决定下载行为的因素

  3. 即使 download 生效,浏览器怎么处理这个下载,也不是统一的

超链接的 download 属性:下载文件时的限制的知识要点示意图
依据已审核正文摘取要点制作的示意图,非实物照片;请结合正文中的条件与范围阅读。要点摘自已审核正文;完整条件与说明见正文。查看高清图解 ↗
本文目录

先回答:download 不是“强制下载”,它只在同源或 blob:、data: 下起作用

如果你在页面上写了一个带 download 属性的链接,想让它点击后下载文件,先要接受一个前提:这个属性只在同源 URL 或 blob:、data: 协议下起作用。

依据是 MDN 对 a 元素 download 属性的说明:download 导致浏览器将链接的 URL 视为下载资源,但备注里明确写了“download 只在同源 URL 或 blob:、data: 协议起作用”。

这意味着两件事。第一,如果链接指向另一个域名下的文件,download 属性会被忽略,浏览器按普通链接处理,可能直接打开或跳转。第二,同源指的是协议、主机、端口三者都相同。比如你的练习页在本地打开,链接指向同一个练习目录下的文本文件,这属于同源;链接指向 example.test 上的文件,就不属于同源。

本文只讨论同源 download、文件名提示和浏览器行为差异,并且只下载你自己创建的文本样例。不涉及跨域下载技巧,也不涉及任何真实文件。

一个自建情境(示例,不是对某个真实网站的记录):你在练习目录里放了一个自己写的页面,页面上有一个链接指向同目录下的 notes.txt,链接上写了 download。点击后浏览器会把它当下载资源处理。如果把这个链接改成指向 example.test 上的文件,download 就不再起作用。

文件名提示:download 的值怎么被浏览器使用

download 属性可以带值,也可以不带值,两种写法对文件名的影响不同。

按 MDN 的说明:如果没有指定值,浏览器会从多个来源决定文件名和扩展名,包括 Content-Disposition HTTP 标头、URL 路径的最后一段、媒体类型(来自 Content-Type 标头、data: URL 的开头,或 blob: URL 的 Blob.type)。如果指定了 filename,这个值就用来决定文件名。

这里有一个容易忽略的细节:filename 里的斜杠和反斜杠会被转化为下划线。MDN 的原话是“/ 和 \ 被转化为下划线(_)”。文件系统还可能阻止文件名中其他的字符,因此浏览器会在必要时适当调整文件名。

所以 download 的值是一个“文件名提示”,不是最终文件名的保证。你写 download="练习笔记.txt",浏览器可能按这个提示保存,也可能因为文件系统限制而调整。

一个自建示例(不是对某款浏览器的实测记录):在练习目录里新建一个文本文件,内容自己写,保存为 notes.txt。然后在同目录的练习页面里写一个链接,href 指向 notes.txt,download 的值写成 我的练习笔记.txt。点击后观察浏览器给出的文件名提示。这个观察只针对你自己创建的文件。

Content-Disposition 与 download 冲突时,谁优先

download 属性不是唯一决定下载行为的因素。服务器返回的 Content-Disposition 标头可能和它冲突,这时行为会按标头走。

按 MDN 的说明:如果 Content-Disposition 标头指定了 filename,它将优先于 download 属性中指定的文件名。如果标头指定了 inline 的处置方式,Chrome 和 Firefox 会优先考虑该属性并将其视为下载资源;旧的 Firefox 浏览器(版本 82 之前)优先考虑该标头,并将内联显示内容。

这句话给出两个判断点。第一,文件名冲突时,标头里的 filename 赢。第二,处置方式冲突时,现代 Chrome 和 Firefox 会把 inline 也当成下载处理,但旧版 Firefox 会按 inline 显示。

对初学者来说,这意味着:如果你只控制页面上的 download 属性,不控制服务器返回的标头,最终文件名和是否下载就不完全由你决定。本文只讲这个冲突关系,不教如何修改服务器标头,也不涉及任何真实服务器配置。

浏览器行为差异:提示、自动保存还是自动打开

即使 download 生效,浏览器怎么处理这个下载,也不是统一的。

按 MDN 的说明:浏览器对待下载的方式因浏览器、用户设置和其他因素而异。在下载开始之前,可能会提示用户,或者自动保存文件,或者自动打开。自动打开要么在外部应用程序中,要么在浏览器本身中。

这句话列了三种可能:提示、自动保存、自动打开。也就是说,同一个带 download 的链接,在不同浏览器或不同用户设置下,可能给出完全不同的结果。

所以“点击后一定会弹出保存对话框”这个预期是不成立的。资料没有给出各浏览器的默认行为清单,本文也不补。你能做的是:在自己的练习页面上点击一次,记录你看到的实际行为,而不是假设所有浏览器都一样。

一个自建情境(示例,不是对某个真实浏览器的测试记录):你在练习目录里用同一个链接分别在本机两个浏览器中打开,观察一个是直接保存、一个是弹出提示。这个差异属于资料所说的“因浏览器、用户设置和其他因素而异”,不是代码写错了。

只下载自己创建的文本样例:一个可核对的练习流程

下面这套流程只操作你自己创建的文本文件,不涉及任何真实数据。建议先复制一份练习目录,不要拿重要文件直接试。

第一步,在练习目录里新建一个文本文件,例如 exercise/notes.txt,内容自己写,保存为 UTF-8。

第二步,在同目录新建一个练习页面,例如 exercise/index.html,里面写一个链接,href 指向 notes.txt,并加上 download 属性。

第三步,用浏览器打开这个练习页面,点击链接,记录三件事:浏览器有没有提示保存、给出的文件名是什么、文件有没有被打开而不是保存。

第四步,把链接的 href 改成指向 example.test 上的一个地址,再点一次,观察 download 是否还起作用。这一步只用于对照,不需要真的下载到文件。

这套流程的输入是你自己写的文本文件和练习页面,输出是你记录下来的浏览器行为。它不能用来证明某个浏览器一定如何,只能作为你这次观察的记录。

检查结果与错误排查:download 没生效时先看什么

如果点击链接后 download 看起来没起作用,可以按下面几项依次检查。

第一,检查是不是同源。看链接的 href 和当前页面的协议、主机、端口是否一致。不一致时,download 按资料说明不起作用。

第二,检查链接是不是 blob: 或 data: 协议。资料说明 download 在这两种协议下也起作用,但它们的文件名来源和普通 URL 不同。

第三,检查服务器有没有返回 Content-Disposition 标头。如果标头里指定了 filename,它会优先于 download 的值;如果标头是 inline,现代 Chrome 和 Firefox 会把它当下载处理,旧版 Firefox 会内联显示。

第四,检查浏览器设置。资料说明浏览器可能提示、自动保存或自动打开,这些行为受用户设置影响。

以上检查顺序是编辑整理的排查方向,不是对某个浏览器的测试结论。资料没有给出各浏览器的默认设置清单,本文也不补。

使用限制与参考资料

本文的适用范围有限,需要明确几点。

第一,本文只讲同源 download、文件名提示和浏览器行为差异,不涉及跨域下载、不涉及服务器标头的修改方法、不涉及任何真实文件或真实网站。

第二,本文所有示例都是自建的练习文件和练习页面,不是对某个真实网站的测试记录,也不是对某款浏览器的实测结论。

第三,资料没有给出各浏览器的默认行为清单,也没有给出文件名被调整的具体规则,本文不补这些内容。

第四,download 属性只是给浏览器一个提示,它不保证文件名一定按你写的保存,也不保证一定弹出保存对话框。

参考资料:MDN 的 a 元素页面,其中 download 属性的说明是本文事实依据的来源。

观看知识要点视频 18 秒

18秒无旁白要点导览,文字来自已审核正文;完整步骤、条件及参考资料见下方。

参考资料

以下原始资料提供本文依据;请结合日期、适用条件和产品说明查阅。

请结合原始资料的适用条件阅读。

返回浏览器工具 →