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

Rgr*_*hat 138 pdf google-chrome

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

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

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

这次我的具体问题网址在这里(Google 搜索结果)。

Bob*_*Bob 174

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


Content-Disposition

这通常是因为站点Content-Disposition在响应中发送了一个标头。具体来说,它可以发送inlineattachment

inline 如果未另行指定,则为默认值,表示浏览器将在浏览器窗口中打开文件(如果可以)。

attachment 意味着始终下载文件,永远不要尝试在浏览器中打开它。


如果您打开浏览器的开发人员工具,您会看到该特定链接发送以下响应标头:

Content-Disposition: attachment; filename="Schubert-Sonata-21-B-flat.pdf"
Content-Type: application/pdf
Run Code Online (Sandbox Code Playgroud)

这告诉浏览器总是下载( attachment) 文件,并为其提供默认文件名Schubert-Sonata-21-B-flat.pdf而不是从 URL 推断它。此外,它确实告诉浏览器(正确地)它是一个application/pdf文件 - 但由于它是一个attachment浏览器仍将默认下载。


内联处理细节

当 aContent-Disposition内联(或未指定)时,浏览器将尝试在默认嵌入式查看器中打开文件。这仅在浏览器知道它是什么文件类型并且浏览器知道如何打开该类型时才有效。

类型检测

文件类型可以由服务器用Content-Type标头指定。例如,最常见的内联类型是text/html,application/javascripttext/css,它们构成了现代网站的三个主要部分。您还可以拥有更深奥的类型,例如application/pdf.

另一种可能是服务器已经指定了Content-Typeapplication/octet-stream。这是最通用的类​​型,它告诉浏览器该文件只是任意数据——此时浏览器唯一能做的就是下载它(理论上——我们会谈到这一点)。

Content-Type服务器未指定a时(有时甚至指定了),浏览器可以执行所谓的嗅探,通过读取文件和查找模式来尝试猜测类型。

类型处理

在接收到具有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 和后来的 Google Chrome 中,它们是 NPAPI 插件。这些插件能够做任何其他程序可以做的所有事情,并且还可以将自己注册为特定文件类型的处理程序,否则浏览器可能无法识别这些文件类型。(顺便说一句,这后来被发现是一个巨大的安全隐患,逐渐放弃了对这些强大插件的支持......)

在插件时代,你会去安装 Adob​​e Acrobat Reader,然后它会安装一个 ActiveX 或 NPAPI 插件,该插件会注册application/pdfMIME 类型并告诉浏览器使用插件内嵌打开这些类型。

当然,在这些插件引起了许多安全和性能问题之后,主要的浏览器供应商决定合并他们自己的 PDF 查看器,同时逐步停止对大多数插件的支持。我们仍然看到的唯一一个是 Adob​​e Shockwave Flash,它处理application/x-shockwave-flash.

实际上还有一些剩余的控件,例如在 Firefox 中,该Preview in Firefox选项仍然存在:

选项截图

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

注册类型的截图

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

  • 使用值“inline”和“attachment”的原因是因为 Content-Disposition 最初是为 MIME 电子邮件指定的,这些值更合适:) (2认同)

Rgr*_*hat 23

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

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

  • 确实 - 这个逻辑覆盖了内容配置,因此很重要。 (3认同)

bwD*_*aco 22

这是因为HTTPContent-Disposition标头指定文件是附件。这会指示浏览器下载文件,而不是直接打开它。

有一个 Chrome 插件可以覆盖此行为。下图来自 Firefox 开发者工具:

在 Firefox 开发工具中看到的 HTTP 请求

  • @davyjones 你可以。这样您就不必询问是否有 Firefox 附加组件,[这里](https://addons.mozilla.org/en-GB/firefox/addon/bypass-forced-download/) 一个是。 (3认同)
  • 这个其他扩展似乎可以工作:https://chrome.google.com/webstore/detail/no-pdf-download/ikhahkidgnljlniknmendeflkdlfhonj (3认同)

归档时间:

查看次数:

69498 次

最近记录:

8 年 前