基本上,这是因为网站告诉浏览器这样做。偶尔,这是因为网站开发人员决定他们想要这种行为,例如常见于文件共享站点。其他时候,这是因为它是他们正在使用的任何软件的默认选项(例如论坛或博客软件)。有时这是因为网站开发人员不知道他们在做什么。
Content-Disposition
这通常是因为该网站发送了一个 Content-Disposition
响应中的标头。具体来说,它可以发送 inline
要么 attachment
。
inline
如果没有另外指定,则为默认值,表示浏览器将在浏览器窗口中打开文件。
attachment
意味着始终下载文件,永远不要尝试在浏览器中打开它。
如果您打开浏览器的开发人员工具,您将看到特定链接发送以下响应标头:
Content-Disposition: attachment; filename="Schubert-Sonata-21-B-flat.pdf"
Content-Type: application/pdf
这告诉浏览器 总是下载 ( attachment
)文件,并给它默认的文件名 Schubert-Sonata-21-B-flat.pdf
而不是从URL推断它。此外,它确实告诉浏览器(正确)它是一个 application/pdf
文件 - 但因为它是一个 attachment
浏览器仍然默认下载。
内联处理细节
当一个 Content-Disposition
如果是内联(或未指定),浏览器将尝试在默认的嵌入式查看器中打开该文件。这仅在浏览器知道它是什么文件类型时有效, 和 浏览器知道如何打开该类型。
类型检测
服务器可以使用a指定文件类型 Content-Type
头。例如,最常见的内联类型是 text/html
, application/javascript
和 text/css
,构成现代网站的三个主要部分。你也可以有更多深奥的类型 application/pdf
。
另一种可能性是服务器指定了一个 Content-Type
的 application/octet-stream
。这是最通用的类型,它告诉浏览器该文件只是任意数据 - 此时浏览器唯一能做的就是下载它(理论上 - 我们会这样做)。
当一个 Content-Type
服务器未指定(有时甚至是指定的),浏览器可以执行所谓的操作 嗅探 尝试通过读取文件并查找模式来猜测类型。
类型处理
收到带有的文件后 inline
或者未指定的处置,浏览器需要尝试在浏览器中打开它。为此,它会查看文件类型,如果它识别出类型,它将尝试打开它。大多数浏览器都会打开 text/
键入一个简单的文本查看器,将尝试渲染 text/html
作为一个网页,可能 打开 application/json
在特殊的语法突出显示器中 等等..
类型 application/octet-stream
是专门处理的。由于它应该是最通用的类型,表示任意字节流,因此不应该有任何处理程序可以应用于此“类型”的所有文件。例如,在Firefox中, 这表现为无法设置默认处理程序 对于 application/octet-stream
。
有些网站也使用非标准类型。我见过 application/force-download
使用 - 最终作为下载,因为浏览器无法识别或知道该类型还有什么,但不享受特殊处理 application/octet-stream
确实。
一点历史课
要了解如何处理PDF,我们可以深入研究一下网络历史记录。在过去,浏览器不知道PDF是什么。所以他们无法打开它。但是我们已经看到在内置PDF查看器之前很久就在浏览器中打开了PDF,那么它是如何工作的呢?
过去可以扩展浏览器功能,远远超过现在使用有限扩展/插件所做的控制。那些通常被称为 插件 。在Internet Explorer中,它们是ActiveX控件;在Mozilla Firefox和后来的谷歌Chrome中,它们是NPAPI插件。这些插件能够执行任何其他程序可以执行的所有操作,并且还可以将自身注册为特定文件类型的处理程序,否则浏览器可能无法识别这些文件类型。 (顺便说一句,后来发现这是一个巨大的安全风险,对这些强大的插件的支持逐渐下降......)
在插件的时代,你会去安装Adobe Acrobat Reader,然后安装一个ActiveX或NPAPI插件来注册 application/pdf
MIME类型并告诉浏览器使用插件内联打开这些类型。
当然,在由这些插件引起的一系列安全性和性能问题之后,主要的浏览器供应商决定合并他们自己的PDF查看器,同时逐步取消对大多数插件的支持。我们仍然看到的唯一一个是Adobe Shockwave Flash,它可以处理 application/x-shockwave-flash
。
实际上还有一些剩余的控件,例如在Firefox中 Preview in Firefox
选项仍然存在:
在过去,这将允许在注册该类型的多个插件之间进行选择。例如,Flash的已注册类型列表:
那些日子也是在HTML5附带的许多媒体支持之前。它不仅仅是PDF - 你的浏览器根本不知道如何处理MP4容器或H.264视频,不知道如何播放MP3文件等等。你会看到媒体播放器提供的插件,如VLC甚至Windows Media Player或网站都会嵌入Flash内置的媒体播放器。
Content-Type: application/octet-stream
但这些日子不那么常见了。