HTTP协议中的Content-Encoding
HTTP協議中的Content-Encoding
主要內容
? ? 1.Content-Encoding是什么
? ? 2.內容編碼格式gzip和deflate
Content-Encoding是什么
Accept-Encoding和Content-Encoding是HTTP中用來對采用哪種編碼格式傳輸正文進行協定的一對頭部字段。
工作原理如下:
? ? 1.首先瀏覽器(也就是客戶端)發送請求時,通過Accept-Encoding帶上自己支持的內容編碼格式列表;
? ? 2.服務端在接收到請求后,從中挑選出一種用來對響應信息進行編碼,并通過Content-Encoding來說明服務端選定的編碼信息
? ? 3.瀏覽器在拿到響應正文后,依據Content-Encoding進行解壓。
? ? ? ? ? ? ? ? 服務端也可以返回未壓縮的正文,但這種情況不允許返回Content-Encoding
內容編碼的目的是優化傳輸內容的大小,通俗地講就是盡心壓縮。一般經過gzip壓縮的文本響應,只要原始大小的1/4(這個數據我現在還不確定)。對于文本類響應是否開啟了內容壓縮,使我們做性能優化時首先要檢查的重要項目;而對于JPG/PNG這類本身已經高度壓縮過的二進制文件,不推介開啟內容壓縮,效果幾乎微乎其微,還浪費cpu
內容的編碼針對的只是傳輸正文。在HTTP/1中,頭部始終是以ASCII文本傳輸,沒有經過任何壓縮。不過這個問題在HTTP/2中已經解決,詳見HTTP/2 頭部壓縮技術介紹
內容編碼使用特別廣泛,理解起來也特別簡單,但是要注意的是不要把它與HTTP中的另外一個概念:傳輸編碼Transfer-Encoding搞混即可。
內容編碼格式gzip和deflate
開始之前,先來介紹三種數據壓縮格式:
- DEFLATE,是一種使用Lempel-Ziv壓縮算法(LZ77)和哈夫曼編碼的數據壓縮格式。定義了RFC 1951 : DEFLATE Compressed Data Format Specification;
- ZLIB,是一種使用DEFLATE的數據壓縮格式。定義于RFC 1950 : ZLIB Compressed Data Format Specification;
- GZIP,是一種使用DEFLATE的文件格式。定義于RFC 1952 : GZIP file format specification
在HTTP/1.1的初始規范RFC 2616的[3.5 Content Codings],這一節中,這樣定義了Content-Encoding中的gzip和deflate:
- ? ? gzip,一種由文件壓縮程序[Gzip,GUN zip]產生的編碼格式,描述于[DEFLATE]壓縮機制是一種具有32位CRC的Lempel-Ziv編碼(LZ77);
- ? ? deflate,由定義于RFC 1950的[ZLIB]編碼格式與RFC 1951中描述的[DEFLATE]壓縮機制組合而成的產物;
RFC 2616對Content-Encoding中的gzip的定義很清晰,它就是指在RFC 1952中定義的GZIP編碼格式;但對deflate的定義含糊不清,實際上它值的是RFC 1950中定義的ZLIB編碼格式,但deflate這個名字特別容易誤會。
在Zlib庫的官方網站,有這么一條FAQ:What’s the difference between the “gzip” and “deflate” HTTP 1.1 encodings??就是在討論HTTP/1.1對deflate的錯誤命名:
? Q:在HTTP/1.1的Content-Encoding中,gzip和deflate的區別是什么?
? A:gzip是指GZIP格式,deflate是指ZLIB格式。HTTP/1.1的作者或許應該將后者稱之為zlib,從而避免與原始的 DEFLATE 數據格式產生混淆。雖然 HTTP/1.1 RFC 2016 正確指出,Content-Encoding 中的 deflate 就是 RFC 1950 描述的 ZLIB,但仍然有報告顯示部分服務器及瀏覽器錯誤地生成或期望收到原始的 DEFLATE 格式,特別是微軟。所以雖然使用 ZLIB 更為高效(實際上這正是 ZLIB 的設計目標),但使用 GZIP 格式可能更為可靠,這一切都是因為 HTTP/1.1 的作者不幸地選擇了錯誤的命名。
結論:在 HTTP/1.1 的 Content-Encoding 中,請使用 gzip。
在 HTTP/1.1 的修訂版 RFC 7230 的?4.2 Compression Codings?這一節中,徹底明確了 deflate 的含義,對 gzip 也做了補充:
-
deflate,包含「使用 Lempel-Ziv 壓縮算法(LZ77)和哈夫曼編碼的 DEFLATE 壓縮數據流(RFC 1951)」的 ZLIB 數據格式(RFC 1950)。
注:一些不符合規范的實現會發送沒有經過 ZLIB 包裝的 DEFLATE 壓縮數據;
-
gzip,具有 32 位循環冗余檢查(CRC)的 LZ77 編碼,通常由 Gzip 文件壓縮程序(RFC 1952)產生。接受方應該將 x-gzip 視為 gzip;
總結一下,HTTP標準中定義的Content-Encoding:deflate,實際上指的是ZLIB編碼(RFC 1950).但由于RFC2616中含糊不清的定義,導致IE錯誤地實現為只接受原始DEFLATE(rfc 1951)。為空兼容IE,我們只能使用Content-Encoding:gzip進行內容編碼,他指的是GZIP編碼(RFC 1952)
其實上,ZLIB 和 DEFLATE 的差別很小:ZLIB 數據去掉 2 字節的 ZLIB 頭,再忽略最后 4 字節的校驗和,就變成了 DEFLATE 數據。
在 Fiddler 增加以下處理,就可以讓 IE 支持標準的 Content-Encoding: deflate(ZLIB 編碼):
if ((compressedData.Length > 2) &&((compressedData[0] & 0xF) == 0x8) && //Low 4-bits must be 8((compressedData[0] & 0x80) == 0) && //High-bit must be clear((((compressedData[0] << 8) + compressedData[1]) % 31) == 0))//Validate checksum {Debug.Write("Fiddler: Ignoring RFC1950 Header bytes for DEFLATE");iStartOffset = 2; }由于其他瀏覽器也能解析原始DEFLATE,所以有些WEB應用干脆為了遷就IE直接輸出原始DEFLATE。
轉載:https://imququ.com/post/content-encoding-header-in-http.html
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的HTTP协议中的Content-Encoding的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 看完这篇,你应该知道什么是Linux了~
- 下一篇: (转)fatal error C1853