內容嗅探,也被稱爲媒體類型嗅探或MIME嗅探,是檢查一個字節流的內容,試圖推斷其中數據的文件格式的作法。內容嗅探一般用在媒體類型沒有被準確指定的狀況,用於補償元數據信息。html
本文將會講解內容嗅探的經常使用場景和可能出現的問題。算法
MIME的全稱是Multipurpose Internet Mail Extensions,多用途互聯網郵件擴展。它是一種標準,它代表了文檔、文件或各類字節的性質和格式。它是在IETF的RFC 6838中定義的。互聯網編號分配機構(IANA)負責定義全部官方的MIME類型。瀏覽器
MIME的結構包含兩部分,分別是type和subtype,他們以 / 來進行分割:安全
type/subtype
類型表明數據類型所屬的通常類別,如視頻或文本。子類型肯定MIME類型所表明的指定類型的確切數據種類。例如,對於 MIME 類型的文本,子類型多是 plain(純文本)、html(HTML 源代碼)或日曆(對於 iCalendar/.ics)文件。服務器
每種類型都有它本身的一套可能的子類型, 一個MIME類型必須包含一個類型和一個子類型。app
還能夠在後面加上額外的參數:ide
type/subtype;parameter=value
例如,對於主類型是text的任何MIME類型,可選的charset參數能夠用來指定數據中字符的字符集。若是沒有指定字符集,默認爲ASCII (US-ASCII),除非被用戶代理的設置覆蓋。要指定UTF-8文本文件,則使用MIME類型text/plain;charset=UTF-8。svg
MIME類型不區分大小寫,但傳統上用小寫,但參數值除外,由於參數值的大小寫可能有或沒有特定的意義。網站
MIME有兩中類型,分別是discrete 和multipart。代理
離散類型是表明單一文件或媒介的類型,如單一文本或音樂文件,或單一視頻。
多部分類型是指由多個組件組成的文件,每一個組件都有本身獨立的MIME類型;或者,指封裝在一個事務中一塊兒發送的多個文件。例如,電子郵件中多個附件就是一種多部分MIME類型。
咱們看下常見的discrete類型:
application/octet-stream
,application/pdf
,application/pkcs8
和application/zip
等。audio/mpeg
,audio/vorbis
。font/woff
,font/ttf
和font/otf
。image/jpeg
,image/png
和image/svg+xml
。model/3mf
和model/vml
。text/plain
, text/csv
和 text/html
.video/mp4
。常見的Multipart類型以下:
message/rfc822
和message/partial
。multipart/byteranges
。由於瀏覽器使用MIME類型,而不是文件擴展名來決定如何處理一個URL,因此Web服務器在響應的Content-Type頭中發送正確的MIME類型很是重要。若是沒有正確配置,瀏覽器極可能會誤解文件的內容,網站將沒法正常運行,下載的文件也可能會被錯誤處理。
爲了解決這個問題,或者說是更好的用戶體驗,不少瀏覽器會進行MIME內容嗅探,也就是經過解析文件的內容,來猜想MIME類型的格式。
不一樣的瀏覽器處理MIME嗅探的方式是不同的。可是他們均可能會產生嚴重的安全漏洞,由於有些MIME類型是可執行類型的,惡意攻擊者能夠經過混淆MIME嗅探算法,從而使攻擊者能夠進行網站運營者或用戶都沒有預料到的操做,如跨站腳本攻擊。
若是不想瀏覽器端進行嗅探,能夠在服務端的響應中設置 X-Content-Type-Options
頭,好比:
X-Content-Type-Options: nosniff
這個頭最先是在IE 8中支持的,不過如今全部的瀏覽器基本都支持這個head類型了。
咱們一般須要在JS中判斷瀏覽器是不是IE瀏覽器,而後作響應的處理:
var isIEBrowser = false; if (window.ActiveXObject) { isIEBrowser = true; } // Or, shorter: var isIE = (window.ActiveXObject !== undefined);
上面的例子就是很是簡單的客戶端嗅探,經過判斷window是否有ActiveXObject 這個屬性來肯定這個瀏覽器是不是IE瀏覽器。
本文已收錄於 http://www.flydean.com/content-sniffing/最通俗的解讀,最深入的乾貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!
歡迎關注個人公衆號:「程序那些事」,懂技術,更懂你!