在 HTTP 協議中,Content-Length 與 Transfer-Encoding 是決定訊息體長度與傳輸方式的兩大核心機制。理解它們的優先級、互斥關係與在 Keep-Alive/短連接下的行為差異,對排查傳輸截斷、超時、協議解析錯誤至關重要。
| 概念 | 定義 | 典型值 |
|---|---|---|
| Entity Length | 實體內容原始長度(壓縮前) | 100 KB |
| Transfer Length | 網絡傳輸實際字節數(壓縮後、Chunked 編碼後) | 30 KB (gzip) / 不定 |
| Content-Length | 標示 Transfer Length(非 Entity Length) | Content-Length: 30720 |
| Transfer-Encoding | 標示傳輸編碼方式,如 chunked、gzip | Transfer-Encoding: chunked |
接收端按以下優先級判斷訊息體結束:
0\r\n\r\n 結束標記判定結束,**不可同時存在 Content-Length**(若共存需移除 CL)。若存在 Transfer-Encoding (尤其是 chunked),則禁止發送 Content-Length。 否則接收端行為未定義(大多數實現會忽略 CL 或報協議錯誤)。
常見錯誤場景:後端框架同時設置 Content-Length 與 Transfer-Encoding: chunked,導致 Nginx/客戶端解析異常。
格式:十六進制長度\r\n數據\r\n ... 0\r\n\r\n
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: text/plain
7\r\n
Mozilla\r\n
9\r\n
Developer\r\n
7\r\n
Network\r\n
0\r\n
\r\n
優勢:動態生成內容時無需預知總長度;支援邊生成邊傳輸(流式響應);配合 Trailer 頭傳輸元數據。
| 連接模式 | HTTP/1.0 | HTTP/1.1 (Keep-Alive 默認開啟) |
|---|---|---|
| Content-Length | 可選(無則靠關閉連接判定) | **必須**與 chunked 二選一 |
| Transfer-Encoding: chunked | 不支援 | **必須**支援,作為無 CL 時的標準方案 |
| 無長度指示 | 靠連接關閉判定 | 協議錯誤(除非關閉連接) |
Transfer-Encoding: chunked。Content-Range 與 Content-Length(分片長度)。Content-Length 表示傳輸長度,而非實體長度。 HTTP/1.1 長連接下,傳輸長度指示器**非 CL 即 Chunked**,二者互斥。正確處理壓縮、流式響應、代理轉發時的長度字段重寫,是高效能 HTTP 服務與中間件開發的基本功。