HTTP協議chunk編碼介紹

當客戶端向服務器請求一個靜態頁面或者一張圖片時,服務器可以很清楚的知道內容大小,然後通過Content-Length消息首部字段告訴客戶端需要接收多少數據。但是如果是動態頁面等時,服務器是不可能預先知道內容大小,這時就可以使用Transfer-Encoding:chunk模式來傳輸數據了。即如果要一邊產生數據,一邊發給客戶端,服務器就需要使用"Transfer-Encoding: chunked"這樣的方式來代替Content-Length。

在進行chunked編碼傳輸時,在回覆消息的頭部有Transfer-Encoding: chunked

編碼使用若干個chunk組成,由一個標明長度爲0的chunk結束。每個chunk有兩部分組成,第一部分是該chunk的長度,第二部分就是指定長度的內容,每個部分用CRLF隔開。在最後一個長度爲0的chunk中的內容是稱爲footer的內容,是一些沒有寫的頭部內容。

chunk編碼格式如下:

[chunk size][\r\n][chunk data][\r\n][chunk size][\r\n][chunk data][\r\n][chunk size = 0][\r\n][\r\n]

chunk size是以十六進制的ASCII碼錶示,比如:頭部是3134這兩個字節,表示的是1和4這兩個ascii字符,被http協議解釋爲十六進制數14,也就是十進制的20,後面緊跟[\r\n](0d 0a),再接着是連續的20個字節的chunk正文。chunk數據以0長度的chunk塊結束,也就是(30 0d 0a 0d 0a)。

分塊傳輸編碼
分塊傳輸編碼(Chunked transfer encoding)是超文本傳輸協議(HTTP)中的一種數據傳輸機制,允許HTTP由網頁服務器發送給客戶端應用( 通常是網頁瀏覽器)的數據可以分成多個部分。分塊傳輸編碼只在HTTP協議1.1版本(HTTP/1.1)中提供。
通常,HTTP應答消息中發送的數據是整個發送的,Content-Length消息頭字段表示數據的長度。數據的長度很重要,因爲客戶端需要知道哪裏是應答消息的結束,以及後續應答消息的開始。然而,使用分塊傳輸編碼,數據分解成一系列數據塊,並以一個或多個塊發送,這樣服務器可以發送數據而不需要預先知道發送內容的總大小。通常數據塊的大小是一致的,但也不總是這種情況。

原理
HTTP 1.1引入分塊傳輸編碼提供了以下幾點好處:

HTTP分塊傳輸編碼允許服務器爲動態生成的內容維持HTTP持久鏈接。通常,持久鏈接需要服務器在開始發送消息體前發送Content-Length消息頭字段,但是對於動態生成的內容來說,在內容創建完之前是不可知的。

分塊傳輸編碼允許服務器在最後發送消息頭字段。對於那些頭字段值在內容被生成之前無法知道的情形非常重要,例如消息的內容要使用散列進行簽名,散列的結果通過HTTP消息頭字段進行傳輸。沒有分塊傳輸編碼時,服務器必須緩衝內容直到完成後計算頭字段的值並在發送內容前發送這些頭字段的值。

HTTP服務器有時使用壓縮 (gzip或deflate)以縮短傳輸花費的時間。分塊傳輸編碼可以用來分隔壓縮對象的多個部分。在這種情況下,塊不是分別壓縮的,而是整個負載進行壓縮,壓縮的輸出使用本文描述的方案進行分塊傳輸。在壓縮的情形中,分塊編碼有利於一邊進行壓縮一邊發送數據,而不是先完成壓縮過程以得知壓縮後數據的大小。


格式
如果一個HTTP消息(請求消息或應答消息)的Transfer-Encoding消息頭的值爲chunked,那麼,消息體由數量未定的塊組成,並以最後一個大小爲0的塊爲結束。每一個非空的塊都以該塊包含數據的字節數(字節數以十六進制表示)開始,跟隨一個CRLF (回車及換行),然後是數據本身,最後塊CRLF結束。在一些實現中,塊大小和CRLF之間填充有白空格(0x20)。最後一塊是單行,由塊大小(0),一些可選的填充白空格,以及CRLF。最後一塊不再包含任何數據,但是可以發送可選的尾部,包括消息頭字段。消息最後以CRLF結尾。

例子
編碼的應答
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked

25
This is the data in the first chunk

1C
and this is the second one

3
con

8
sequence

0

編碼應答的解釋[編輯]
前兩個塊的數據中包含有顯式的\r\n字符。
"This is the data in the first chunk\r\n"      (37 字符 => 十六進制: 0x25)
"and this is the second one\r\n"            (28 字符 => 十六進制: 0x1C)
"con"                              ( 3 字符 => 十六進制: 0x03)
"sequence"                          ( 8 字符 => 十六進制: 0x08)
應答需要以0長度的塊( "0\r\n\r\n".)結束。

解碼的數據[編輯]
This is the data in the first chunk
and this is the second one
consequence

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章