首页/网络/协议速查/Transfer-Encoding 传输编码
HTTP 头与缓存70 条

Transfer-Encoding 传输编码

逐跳的报文传输编码:HTTP/1.1 的标准值是 chunked(分块),解决长度未知时的流式传输。

协议速查网络更新于 2026-10-13

报文分帧的方式

Transfer-Encoding 描述报文自身的传输编码,是逐跳字段而不是内容属性。HTTP/1.1 中唯一的标准取值是 chunked:把正文切成若干块,每块前面带十六进制长度,最后以长度 0 的块结束。它的价值在于长度未知时也能流式发送——服务端边生成边推送,不必先缓冲整个响应。

基本信息

方向请求与响应都可出现,属于逐跳字段
规范RFC 9110 §6.1,报文分帧见 RFC 9112 §6.1
标准取值chunked(分块),历史值 gzip 与 compress 已废弃
HTTP/2 及以上不再使用 chunked,帧自带长度,仅保留 trailers 能力
与 Content-Length同一报文里两者不能同时出现

分块报文结构

片段内容说明
起始行HTTP/1.1 200 OK之后跟 Transfer-Encoding: chunked
块头十六进制长度加换行如 1a 表示后续 26 字节数据
块数据原始数据加换行长度必须与块头声明一致
结束块长度为 0 的块其后的空行结束报文,可在其间放 trailer 字段

分块响应示例

分块响应示例
HTTP/1.1 200 OK
Transfer-Encoding: chunked

1a
(26 字节数据)
15
(21 字节数据)
0

# 每个块:十六进制长度 + 换行 + 数据 + 换行;0 长度块表示结束
# 流式接口(SSE、日志推送)依赖这种边生成边发送的能力
curl -sN https://example.com/stream   # -N 关闭 curl 自身的输出缓冲

典型使用场景

  • 服务端流式输出:SSE、大文件边读边发、日志实时推送
  • 不知道响应总长度时的默认做法,避免先算长度再发送
  • 排查「响应卡住不结束」:看分块流是否缺少 0 长度结束块
  • 网关升级协议时确认 chunked 是否被正确解包再重编码
报文中同时出现 Transfer-Encoding 与 Content-Length 是请求走私的经典素材:不同实现选取哪一个来解释边界,会出现两个解析器看到的报文长度不一致;网关应直接拒绝这种歧义消息。
chunked 是编码不是压缩:它只负责切块与定界,压缩仍由 Content-Encoding 承担,两者可以并存且顺序有讲究——先压缩再分块发送。

易错点

  • 网关解 chunked、后端按 Content-Length 解析:两边边界理解不一致会产生请求走私漏洞,应统一编排层并拒绝歧义报文
  • HTTP/2 网关闭 chunked 转换出错:流式接口(SSE)在升级后卡住或一次性吐出全部缓冲,前端表现为长时间空白
  • 误以为分块响应能被中间缓存整体缓存:chunked 通常意味着长度未知,缓存策略要显式配置,否则回源压力增大
  • 手写测试报文时块长度算错或缺少结束块:服务端一直等待后续数据直到超时,连接池被持续占用

数据来源与参考

  • RFC 9112 §6.1 Transfer-Encoding
  • RFC 9110 §6.1

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌