1、背景: 瀏覽器
- 持續鏈接的問題:對於非持續鏈接,瀏覽器能夠經過鏈接是否關閉來界定請求或響應實體的邊界;而對於持續鏈接,這種方法顯然不奏效。有時,儘管我已經發送完全部數據,但瀏覽器並不知道這一點,它沒法得知這個打開的鏈接上是否還會有新數據進來,只能傻傻地等了。
- 用Content-length解決:計算實體長度,並經過頭部告訴對方。瀏覽器能夠經過 Content-Length 的長度信息,判斷出響應實體已結束
- Content-length引入的新問題:因爲 Content-Length 字段必須真實反映實體長度,可是對於動態生成的內容來講,在內容建立完以前,長度是不可知的。這時候要想準確獲取長度,只能開一個足夠大的 buffer,等內容所有生成好再計算。但這樣作一方面須要更大的內存開銷,另外一方面也會讓客戶端等更久。
- 咱們須要一個新的機制:不依賴頭部的長度信息,也能知道實體的邊界——分塊編碼(Transfer-Encoding: chunked)
2、分塊編碼(Transfer-Encoding: chunked) 服務器
- Transfer-Encoding,是一個 HTTP 頭部字段(響應頭域),字面意思是「傳輸編碼」。最新的 HTTP 規範裏,只定義了一種編碼傳輸:分塊編碼(chunked)。
- 分塊傳輸編碼(Chunked transfer encoding)是超文本傳輸協議(HTTP)中的一種數據傳輸機制,容許HTTP由網頁服務器發送給客戶端的數據能夠分紅多個部分。分塊傳輸編碼只在HTTP協議1.1版本(HTTP/1.1)中提供。
- 數據分解成一系列數據塊,並以一個或多個塊發送,這樣服務器能夠發送數據而不須要預先知道發送內容的總大小。
-
具體方法
- 在頭部加入 Transfer-Encoding: chunked 以後,就表明這個報文采用了分塊編碼。這時,報文中的實體須要改成用一系列分塊來傳輸。
- 每一個分塊包含十六進制的長度值和數據,長度值獨佔一行,長度不包括它結尾的 CRLF(\r\n),也不包括分塊數據結尾的 CRLF。
- 最後一個分塊長度值必須爲 0,對應的分塊數據沒有內容,表示實體結束。
-
例:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked this
25\r\n
This is the data in the first chunk\r\n 編碼
1C\r\n
and this is the second one\r\n spa
3\r\n 內存
con\r\n io
8\r\n
sequence\r\n coding
0\r\n 請求
\r\n 方法
- Content-Encoding 和 Transfer-Encoding 兩者常常會結合來用,其實就是針對 Transfer-Encoding 的分塊再進行 Content-Encoding壓縮。