← 返回题目列表

HTTP 分块传输是什么?Transfer-Encoding: chunked 适合什么场景?

高频 中等 第 12 / 32 题 更新于 2026/07/31
HTTP分块传输Transfer-EncodingChunked流式响应

简化版

Transfer-Encoding: chunked 是 HTTP/1.1 的分块传输机制,服务器可以在不知道完整响应体长度的情况下,边生成边发送。每个 chunk 前面有长度,最后用长度为 0 的 chunk 表示结束。它和 Content-Length 通常二选一:有固定长度就用 Content-Length,动态生成或流式输出时可以用 chunked。它解决的是传输分帧问题,不等于应用层业务分片。

详细版

分块传输适合动态页面、日志流、接口边计算边返回、大文件代理转发等场景。普通固定响应:

Content-Length: 1024

表示客户端提前知道响应体有 1024 字节。分块响应:

Transfer-Encoding: chunked

4
Wiki
5
pedia
0

客户端按 chunk 读取,直到读到 0 长度块。需要注意,chunked 是 HTTP/1.1 的传输编码,不是压缩编码;压缩通常通过 Content-Encoding: gzip/br 表示。

完整版教学

一、为什么需要分块传输

HTTP 响应体如果长度已知,服务器可以直接发送 Content-Length。但很多场景下,响应体长度一开始并不知道:

  • 服务端动态生成内容;
  • 后端边查询边输出;
  • 代理服务器边从上游读边转发;
  • 长连接流式推送部分结果。

这时如果必须等所有内容生成完再算长度,就会增加延迟和内存占用。chunked 允许服务器先发头,再分块发送正文。

二、chunked 的格式长什么样

一个简化的 chunked 响应如下:

HTTP/1.1 200 OK
Transfer-Encoding: chunked

4
Wiki
5
pedia
0

每个块的格式是:

chunk-size\r\n
chunk-data\r\n

最后一个块大小为 0,表示响应体结束。这里的 45 是十六进制长度,不是十进制文本标号。

三、Content-Length 和 Transfer-Encoding 的关系

Content-Length 表示响应体固定长度。客户端读到指定字节数后就知道响应结束。

Transfer-Encoding: chunked 表示响应体由多个块组成,客户端读到 0 长度块才知道结束。

方式是否提前知道总长度结束判断常见场景
Content-Length读取固定字节数静态文件、固定 JSON
chunked读到 0 长度块动态生成、代理转发、流式输出

在 HTTP/1.1 中,chunked 是解决“长度未知但要保持连接复用”的关键机制。

四、它和连接复用有什么关系

HTTP/1.1 默认支持连接复用。同一个 TCP 连接上可能连续传多个响应,客户端必须知道一个响应在哪里结束,才能正确读取下一个响应。

如果没有 Content-Length,又不用 chunked,客户端可能只能靠关闭连接来判断响应结束:

响应体结束 = 服务端关闭 TCP 连接

这会破坏连接复用。chunked 通过 0 长度块明确结束位置,让连接可以继续用于后续请求。

五、chunked 不是压缩,也不是业务分页

容易混淆的几个概念:

概念作用
Transfer-Encoding: chunkedHTTP 传输层面的分块
Content-Encoding: gzip/br内容压缩
Range 请求客户端请求资源的一部分
业务分页应用层按页返回数据

chunked 的每个块只是传输格式的一部分,不代表业务上“一条消息”或“一页数据”。应用协议如果需要消息边界,仍然要自己定义,例如 SSE 的事件格式、JSON Lines 等。

六、代理和网关里的注意点

实际工程里,反向代理、网关、框架都可能改变响应传输方式:

  • 上游 chunked,代理可能缓冲后转成 Content-Length
  • 上游固定长度,代理压缩后可能变成 chunked;
  • 某些网关默认开启响应缓冲,导致流式效果消失;
  • 客户端库可能自动解码 chunked,让业务代码感知不到块边界。

如果你在排查“服务端明明边写边 flush,浏览器为什么收不到”,要同时检查应用框架、代理缓冲、压缩和 HTTP 版本。

七、常见误区与追问

  • 误区:chunked 是一种压缩算法。 chunked 是传输编码,gzip/br 才是常见内容压缩。
  • 误区:使用 chunked 后就不能复用连接。 正好相反,chunked 明确响应结束位置,有利于 HTTP/1.1 连接复用。
  • 误区:chunk 大小就是业务消息大小。 chunk 是传输层面的块,不一定对应业务事件或 JSON 对象。
  • 误区:Content-Length 和 Transfer-Encoding: chunked 可以随便同时用。 两者语义冲突,实际应避免同时发送。
  • 追问:chunked 怎么表示响应结束? 发送一个长度为 0 的 chunk 表示正文结束。
  • 追问:为什么动态响应适合 chunked? 因为服务端可以不知道总长度,边生成边发送,降低首字节等待和内存压力。

八、加强记忆

分块传输的核心是:不知道总长度,也能明确响应边界。固定长度用 Content-Length,动态或流式输出用 Transfer-Encoding: chunked;每块先写长度,再写数据,最后用 0 长度块结束。它不是压缩、不是 Range、不是分页。面试回答时把“长度未知、边生成边发送、保持连接复用”这三个关键词说出来就很稳。