題 為什麼Chrome有時會下載PDF而不是打開它? [重複]


這個問題在這裡已有答案:

當我訪問PDF文件的某些地址時,Chrome會下載PDF而不是使用其內置的PDF查看器打開它。然後該頁面為空白。

我的Chrome設置沒有問題:我嘗試其他PDF文件的地址,Chrome的行為符合預期(我已將其設置為使用Chrome的內置PDF查看器)。但每次我嘗試相同的問題地址時,Chrome都會下載PDF,然後顯示空白頁面。

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

我這次特定的問題網址是 這裡 (Google搜索結果)。


110
2017-12-17 07:00


起源




答案:


基本上,這是因為網站告訴瀏覽器這樣做。偶爾,這是因為網站開發人員決定他們想要這種行為,例如常見於文件共享網站。其他時候,這是因為它是他們使用的任何軟件的默認選項(例如論壇或博客軟件)。有時這是因為網站開發人員不知道他們在做什麼。


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/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 選項仍然存在:

Screenshot of option

在過去,這將允許在註冊該類型的多個插件之間進行選擇。例如,Flash的已註冊類型列表:

Screenshot of registered types

那些日子也是在HTML5附帶的許多媒體支持之前。它不僅僅是PDF - 您的瀏覽器根本不知道如何處理MP4容器或H.264視頻,不知道如何播放MP3文件等等。您會看到媒體播放器提供的插件,如VLC甚至Windows Media Player或網站都會嵌入Flash內置的媒體播放器。


139
2017-12-17 07:04



有時它也會在服務器設置時發生 Content-Type: application/octet-stream 但這些日子不那麼常見了。 - Michael Hampton
使用“內聯”和“附件”值的原因是因為最初為MIME電子郵件指定了Content-Disposition,其中這些值更合適:) - hobbs
@hobbs:幾乎是一個關於可重用技術領域特定術語的案例研究,當更抽象的東西會做^ _ ^ - Lightness Races in Orbit


我找到了解釋。根據一個 回答我發現了,如果MIME內容類型未設置,Chrome似乎會下載PDF application/pdf 而是“不正確或通用的MIME類型”, application/octet-stream

此外,“大多數Web服務器使用默認值發送未知類型的資源 application/octet-stream MIME類型。出於安全原因,大多數瀏覽器不允許為此類資源設置自定義默認操作,強制用戶將其存儲到磁盤以使用它。“


23
2017-12-17 07:05



確實 - 這種邏輯壓倒了內容的傾向,因此很重要。 - Lightness Races in Orbit
@LightnessRacesinOrbit它並沒有那麼多 覆蓋 處置,因為它給瀏覽器一個類型,除了保存到磁盤之外,它不能做任何事情(禁止嗅探)。當然,可見效果是一樣的。 - Bob
@Bob:好的,這是一個公平的解釋 - Lightness Races in Orbit


這是由於 HTTP Content-Disposition 頭 指定該文件是 附件。這指示瀏覽器下載文件,而不是直接打開它。

有一個Chrome插件可以覆蓋此行為。 以下圖片來自Firefox開發人員工具:

HTTP request as seen in the Firefox development tools


20
2017-12-17 07:05



請問是否還有類似的Firefox插件? - davyjones
@davyjones你可以。這樣您就不必詢問是否有Firefox插件, 這裡 一個是。 - wizzwizz4
該插件似乎不再起作用了 - Paul Slocum