为什么Chrome有时会下载PDF而不是打开它? [重复]


112

当我访问PDF文件的某些地址时,Chrome会下载PDF而不是使用其内置的PDF查看器打开它。然后该页面为空白。

我的Chrome设置没有问题:我尝试其他PDF文件的地址,Chrome的行为符合预期(我已将其设置为使用Chrome的内置PDF查看器)。但每次我尝试相同的问题地址时,Chrome都会下载PDF,然后显示空白页面。

我使用的是Windows 10和Chrome Version 63.0.3239.84 (Official Build) (64-bit)

我这次特定的问题网址是 这里 (Google搜索结果)。

Answers:


140

基本上,这是因为网站告诉浏览器这样做。偶尔,这是因为网站开发人员决定他们想要这种行为,例如常见于文件共享站点。其他时候,这是因为它是他们正在使用的任何软件的默认选项(例如论坛或博客软件)。有时这是因为网站开发人员不知道他们在做什么。


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/htmlapplication/javascripttext/css,构成现代网站的三个主要部分。你也可以有更多深奥的类型 application/pdf

另一种可能性是服务器指定了一个 Content-Typeapplication/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 选项仍然存在:

Screenshot of option

在过去,这将允许在注册该类型的多个插件之间进行选择。例如,Flash的已注册类型列表:

Screenshot of registered types

那些日子也是在HTML5附带的许多媒体支持之前。它不仅仅是PDF - 你的浏览器根本不知道如何处理MP4容器或H.264视频,不知道如何播放MP3文件等等。你会看到媒体播放器提供的插件,如VLC甚至Windows Media Player或网站都会嵌入Flash内置的媒体播放器。


有时它也会在服务器设置时发生 Content-Type: application/octet-stream 但这些日子不那么常见了。
Michael Hampton

1
使用“内联”和“附件”值的原因是因为最初为MIME电子邮件指定了Content-Disposition,其中这些值更合适:)
hobbs

@hobbs:几乎是一个关于可重用技术领域特定术语的案例研究,当更抽象的东西会做^ _ ^
Lightness Races in Orbit

23

我找到了解释。根据一个 回答我发现了 ,如果MIME内容类型未设置,Chrome似乎会下载PDF application/pdf 而是“不正确或通用的MIME类型”, application/octet-stream

此外 ,“大多数Web服务器使用默认值发送未知类型的资源 application/octet-stream MIME类型。出于安全原因,大多数浏览器不允许为此类资源设置自定义默认操作,强制用户将其存储到磁盘以使用它。“


3
确实 - 这种逻辑压倒了内容的倾向,因此很重要。
Lightness Races in Orbit

@LightnessRacesinOrbit它并没有那么多 覆盖 这种配置为浏览器提供了一种类型,除了保存到磁盘之外,它不能做任何事情(禁止嗅探)。当然,可见效果是一样的。
Bob

@Bob:好的,这是一个公平的解释
Lightness Races in Orbit

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.