1. 程式人生 > >各瀏覽器對常用或者錯誤的 Content-Type 類型處理方式不一致

各瀏覽器對常用或者錯誤的 Content-Type 類型處理方式不一致

mimetype rac apache。 顯示文件 vid ssi 字符 inf 識別

標準參考

content-type 用於定義用戶的瀏覽器或相關設備如何顯示將要加載的數據,或者如何處理將要加載的數據,此屬性的值可以查看 MIME 類型。

MIME (Multipurpose Internet Mail Extensions,多用途互聯網郵件擴展) 是描述消息內容類型的因特網標準。MIME 消息能包含文本、圖像、音頻、視頻以及其他應用程序專用的數據。

content-type 一般以下面的形式出現:

Content-Type: [type]/[subtype]; parameter

type 有下面的形式:

  • Text:用於標準化地表示的文本信息,文本消息可以是多種字符集和或者多種格式的;
  • Multipart:用於連接消息體的多個部分構成一個消息,這些部分可以是不同類型的數據;
  • Application:用於傳輸應用程序數據或者二進制數據;
  • Message:用於包裝一個E-mail消息;
  • Image:用於傳輸靜態圖片數據;
  • Audio:用於傳輸音頻或者音聲數據;
  • Video:用於傳輸動態影像數據,可以是與音頻編輯在一起的視頻數據格式。

subtype 用於指定 type 的詳細形式。“type/subtype”配對的集合和與此相關的參數。下面是最經常用到的一些 MIME 類型:

  • text/html(HTML 文檔);
  • text/plain(純文本);
  • text/css(CSS 樣式表);
  • image/gif(GIF 圖像);
  • image/jpeg(JPG 圖像);
  • application/x-javascript(JavaScript 腳本);
  • application/x-shockwave-flash(Flash);
  • application/x- www-form-urlencoded(使用 HTTP 的 POST 方法提交的表單);
  • multipart/form-data(同上,但主要用於表單提交時伴隨文件上傳的場合)。

關於 content-type 的詳細信息,請參考 HTML4.01 規範 6.7 Content types (MIME types) 中的內容。

關於 MIME 的相信信息,請參考 IETF 的 [RFC2045] 及 [RFC2046] 規範。

更多的 MIME 類型參見:

  • http://www.utoronto.ca/webdocs/HTMLdocs/Book/Book-3ed/appb/mimetype.html
  • http://www.iana.org/assignments/media-types/

問題描述

Content-Type 報頭字符串代表著服務器端發送給客戶端瀏覽器的具體數據類型,瀏覽器將根據這個信息決定如何處理得到的數據內容。比如:‘Content- Type:text/html‘ 表示著這是個 HTML 文件,需要渲染引擎解釋內容後輸出;‘Content-Type: application/octet-stream‘ 表示這是個二進制流,需要下載到本地後由用戶端環境決定如何使用。

每個瀏覽器內置支持的 Content-Type 類型表各不相同,這導致了某些類型字符串在某些瀏覽器下不被識別;另外,如果出現錯誤的 Content-Type 類型,各個瀏覽器又會以不同的方式處理。

造成的影響

未知的或者是錯誤的 Content-Type 類型,在各個瀏覽器中處理方式不一致,草率對待將有可能使得同一文件在各種瀏覽器中展現方式完全不同。

受影響的瀏覽器

所有瀏覽器

問題分析

創建一個 Web 服務器,如 Apache。在服務器上編寫一段動態代碼,如:ct_test.php

<?php   $contentTypeList = array(     ‘0‘=>‘Content-Type: text/plain‘,     ‘1‘=>‘Content-Type: application/octet-stream‘,     ‘2‘=>‘Content-Type: application/x-rar-compressed‘,     ‘3‘=>‘Content-Type: application/zip‘,     ‘4‘=>‘Content-Type: application/x-shockwave-flash‘,     ‘5‘=>‘Content-Type: video/quicktime‘,     ‘6‘=>‘Content-Type: video/mp4‘,     ‘7‘=>‘Content-Type: audio/mpeg‘,     ‘8‘=>‘Content-Type: image/jpeg‘,     ‘9‘=>‘Content-Type: image/gif‘,     ‘10‘=>‘Content-Type: image/png‘,     ‘11‘=>‘Content-Type: application‘,     ‘12‘=>‘Content-Type: audio‘,     ‘13‘=>‘Content-Type: video‘,     ‘14‘=>‘Content-Type: image‘,     ‘15‘=>‘Content-Type: helloworld‘     );   header($contentTypeList[$_GET["type"]]."; charset=UTF-8"); ?>

PHP 的文件中建立了 16 種 Content-Type 類型,根據 URL 中 GET 參數值選取其中一種文件類型 HTTP 報頭發向客戶端瀏覽器。其中 11 種常用類型,4 種故意寫錯的類型,1 種完全自定義類型:

文件類型Content-Type 類型
常見類型 文本 text/plain
二進制流 application/octet-stream
RAR 壓縮包 application/x-rar-compressed
Zip 壓縮包 application/zip
Flash 文件 application/x-shockwave-flash
QuickTime 視頻 video/quicktime
MP4 視頻 video/mp4
MP3 音頻 audio/mpeg
JPEG 圖片 image/jpeg
GIF 圖片 image/gif
PNG 圖片 image/png
書寫有誤類型 數據 application
音頻 audio
視頻 video
圖像 image
瀏覽器不可識別類型 自定義類型 helloworld

分別以不同 HTTP Content-Type 報頭類型運行此段代碼,在不同的瀏覽器環境中的表現如下:

IE6 IE7 IE8FirefoxChromeSafariOpera
text/plain 顯示文件內容 顯示文件內容 顯示文件內容 顯示文件內容 顯示文件內容
application/octet-stream 顯示文件內容 下載文件 下載文件 下載文件 顯示文件內容
application/x-rar-compressed 下載文件1 下載文件 下載文件 下載文件 下載文件
application/zip 下載文件1 下載文件 下載文件 下載文件 下載文件
application/x-shockwave-flash 試圖顯示 Flash 試圖顯示 Flash 試圖顯示 Flash 試圖顯示 Flash 試圖顯示 Flash
video/quicktime 下載文件 下載文件 下載文件 下載文件 下載文件
video/mp4 下載文件 下載文件 試圖播放視頻3 下載文件 下載文件
audio/mpeg 下載文件 下載文件 試圖播放視頻3 下載文件 下載文件
image/jpeg 顯示文件內容 試圖顯示圖片2 試圖顯示圖片 試圖顯示圖片 試圖顯示圖片
image/gif 顯示文件內容 試圖顯示圖片2 試圖顯示圖片 試圖顯示圖片 試圖顯示圖片
image/png 顯示文件內容 試圖顯示圖片2 試圖顯示圖片 試圖顯示圖片 試圖顯示圖片
application 下載文件1 顯示文件內容 顯示文件內容 下載文件 顯示文件內容
audio 下載文件1 顯示文件內容 顯示文件內容 下載文件 顯示文件內容
video 下載文件1 顯示文件內容 顯示文件內容 下載文件 顯示文件內容
image 下載文件1 顯示文件內容 顯示文件內容 下載文件 顯示文件內容
helloworld 下載文件1 顯示文件內容 顯示文件內容 下載文件 顯示文件內容

【註1】:這幾種 Content-Type 類型在測試環境中的 IE6 IE7 IE8 瀏覽器彈出的下載對話框提示中,均顯示“不可識別類型”

【註2】:Firefox 會將 URL 和一些錯誤信息輸出在圖片格式中顯示。

【註3】:Chrome 試圖使用 VIDEO 標記直接顯示這兩種格式的視頻。

由表可見:

  • IE6 IE7 IE8 對於可以識別的非視頻、音頻流內容均會嗅探其內容,並且根據內容是否正常再決定如何輸出顯示;
    (關於嗅探的擴展閱讀:CH9002: IE6 IE7 IE8 未按預期方式處理 content-type 為 text/plain 的內容)
  • Firefox Chrome 對於未知 Content-Type 的內容均直接顯示其內容,其他類型則以直接以最合適的方式處理;
  • Opera 對於可以識別的視頻、音頻流內容會直接提示下載,圖片類型和 Flash 類型會試圖顯示他們,未知 Content-Type 的內容均直接顯示其內容則直接顯示其內容,但在顯示內容前不會嗅探其中的 HTML 標記。

解決方案

這個問題比較復雜,如需避免出現顯示異常,建議不要使用非法的 Content-Type 頭字符串;並且文件實際內容和數據格式應與 Content-Type 頭字符串內類型聲明一致





ps: 今天碰到一個問題,firefox 輸出shtml 文本輸出,找半天發現apache 沒設置 AddType text/html .shtml 默認的.shtml被當成純文本輸出了

各瀏覽器對常用或者錯誤的 Content-Type 類型處理方式不一致