咱們知道HTTP協議採用「請求-應答」模式,當使用普通模式,即非KeepAlive模式時,每一個請求/應答客戶和服務器都要新建一個鏈接,完成 以後當即斷開鏈接(HTTP協議爲無鏈接的協議);當使用Keep-Alive模式(又稱持久鏈接、鏈接重用)時,Keep-Alive功能使客戶端到服 務器端的鏈接持續有效,當出現對服務器的後繼請求時,Keep-Alive功能避免了創建或者從新創建鏈接。html
Content-Length 是一個實體消息首部,用來指明發送給接收方的消息主體的大小,即用十進制數字表示的八位元組的數目。瀏覽器
當客戶端向服務器請求一個靜態頁面或者一張圖片時,服務器能夠很清楚的知道內容大小,而後經過Content-length消息首部字段告訴客戶端須要接收多少數據。可是若是是動態頁面等時,服務器是不可能預先知道內容大小,這時就可使用Transfer-Encoding:chunk模式來傳輸數據了。即若是要一邊產生數據,一邊發給客戶端,服務器就須要使用"Transfer-Encoding: chunked"這樣的方式來代替Content-Length。服務器
chunk編碼將數據分紅一塊一塊的發生。Chunked編碼將使用若干個Chunk串連而成,由一個標明長度爲0的chunk標示結束。每一個Chunk分爲頭部和正文兩部分,頭部內容指定正文的字符總數(十六進制的數字)和數量單位(通常不寫),正文部分就是指定長度的實際內容,兩部分之間用回車換行(CRLF)隔開。在最後一個長度爲0的Chunk中的內容是稱爲footer的內容,是一些附加的Header信息(一般能夠直接忽略)。ide
Transfer-Encoding 是一個用來標示 HTTP 報文傳輸格式的頭部值。儘管這個取值理論上能夠有不少,可是當前的 HTTP 規範裏實際上只定義了一種傳輸取值——chunked。工具
若是一個HTTP消息(請求消息或應答消息)的Transfer-Encoding消息頭的值爲chunked,那麼,消息體由數量未定的塊組成,並以最後一個大小爲0的塊爲結束。ui
每個非空的塊都以該塊包含數據的字節數(字節數以十六進制表示)開始,跟隨一個CRLF (回車及換行),而後是數據自己,最後塊CRLF結束。在一些實現中,塊大小和CRLF之間填充有白空格(0x20)。this
最後一塊是單行,由塊大小(0),一些可選的填充白空格,以及CRLF。最後一塊再也不包含任何數據,可是能夠發送可選的尾部,包括消息頭字段。消息最後以CRLF結尾。編碼
一個示例響應以下:code
HTTP/1.1 200 OK Content-Type: text/plain Transfer-Encoding: chunked 25 This is the data in the first chunk 1A and this is the second one 0
注意:htm
其實,上面2中方法均可以概括爲是如何判斷http消息的大小、消息的數量。RFC 2616對消息的長度總結以下:一個消息的transfer-length(傳輸長度)是指消息中的message-body(消息體)的長度。當應用了transfer-coding(傳輸編碼),每一個消息中的message-body(消息體)的長度(transfer-length)由如下幾種狀況決定(優先級由高到低):
爲了兼容HTTP/1.0應用程序,HTTP/1.1的請求消息體中必須包含一個合法的Content-Length頭字段,除非知道服務器兼容HTTP/1.1。一個請求包含消息體,而且Content-Length字段沒有給定,若是不能判斷消息的長度,服務器應該用用400 (bad request) 來響應;或者服務器堅持但願收到一個合法的Content-Length字段,用 411 (length required)來響應。
全部HTTP/1.1的接收者應用程序必須接受「chunked」 transfer-coding (傳輸編碼),所以當不能事先知道消息的長度,容許使用這種機制來傳輸消息。消息不該該夠同時包含 Content-Length頭字段和non-identity transfer-coding。若是一個消息同時包含non-identity transfer-coding和Content-Length ,必須忽略Content-Length 。