1. 程式人生 > >http 響應頭裡 沒有 或者有 content-length 的幾種可能性

http 響應頭裡 沒有 或者有 content-length 的幾種可能性

對於http的請求返回結果要進行內容的長度校驗主要有兩種方式,二者互斥使用

1.客戶端在http頭(head)加Connection:keep-alive時,伺服器的response是Transfer-Encoding:chunked的形式,通知頁面資料是否接收完畢,例如長連線或者程式執行中可以動態的輸出內容,例如一些運算比較複雜且需要使用者及時的得到最新結果,那就採用chunked編碼將內容分塊輸出。

2.除了如1所述之外的情況一般都是可以獲取到Content-Length的。

在HTTP協議中,Content-Length用於描述HTTP訊息實體的傳輸長度the transfer-length of the message-body。在HTTP協議中,訊息實體長度和訊息實體的傳輸長度是有區別,比如說gzip壓縮下,訊息實體長度是壓縮前的長度,訊息實體的傳輸長度是gzip壓縮後的長度。

在具體的HTTP互動中,客戶端是如何獲取訊息長度的呢,主要基於以下幾個規則:

  • 響應為1xx,204,304相應或者head請求,則直接忽視掉訊息實體內容。
  • 如果有Transfer-Encoding,則優先採用Transfer-Encoding裡面的方法來找到對應的長度。比如說Chunked模式。
  • “如果head中有Content-Length,那麼這個Content-Length既表示實體長度,又表示傳輸長度。如果實體長度和傳輸長度不相等(比如說設定了Transfer-Encoding),那麼則不能設定Content-Length。如果設定了Transfer-Encoding,那麼Content-Length將被忽視”。這句話翻譯的優點饒,其實關鍵就一點:有了Transfer-Encoding,則不能有Content-Length。
  • Range傳輸。不關注,沒詳細看了:)
  • 通過伺服器關閉連線能確定訊息的傳輸長度。(請求端不能通過關閉連線來指明請求訊息體的結束,因為這樣可以讓伺服器沒有機會繼續給予響應)。這種情況主要對應為短連線,即非keep-alive模式。
  • HTTP1.1必須支援chunk模式。因為當不確定訊息長度的時候,可以通過chunk機制來處理這種情況。
  • 在包含訊息內容的header中,如果有content-length欄位,那麼該欄位對應的值必須完全和訊息主題裡面的長度匹配。
    “The entity-length of a message is the length of the message-body before any transfer-codings have been applied”
    也就是有chunk就不能有content-length 。

其實後面幾條几乎可以忽視,簡單總結後如下:

1、Content-Length如果存在並且有效的話,則必須和訊息內容的傳輸長度完全一致。(經過測試,如果過短則會截斷,過長則會導致超時。)

2、如果存在Transfer-Encoding(重點是chunked),則在header中不能有Content-Length,有也會被忽視。

3、如果採用短連線,則直接可以通過伺服器關閉連線來確定訊息的傳輸長度。(這個很容易懂)

結合HTTP協議其他的特點,比如說Http1.1之前的不支援keep alive。那麼可以得出以下結論:

1、在Http 1.0及之前版本中,content-length欄位可有可無。

2、在http1.1及之後版本。如果是keep alive,則content-length和chunk必然是二選一。若是非keep alive,則和http1.0一樣。content-length可有可無

我總結我的例子   如果  要是 js  css  html 這樣的檔案的話   會返回 contengt-length  位元組  前提是    nginx 裡的gzip  off   如果是on 的話   返回  chunk

執行的如果是 動態 指令碼的話,    還是返回chunk 前提是  content:keep-alive     如果不是長連線的話   返回的頭裡面沒有content-leght   ()