nginx默认可透传chunked,但需配置proxy_http_version 1.1;、proxy_buffering off;和proxy_set_header connection '';三者协同才能真实边收边发;否则默认缓冲会改写为content-length响应。

要让 Nginx 在负载均衡(upstream)场景下正确透传后端的 chunked 编码响应,关键不是“是否支持”,而是配置是否阻止了 chunked 的流转。Nginx 默认能透传 chunked,但默认配置会悄悄把它吃掉、改写、甚至降级为定长响应。
chunked 在 upstream 中的流转前提
Nginx 本身不生成 chunked(除非作为 origin server 并显式开启),它只做代理透传或适配。能否真实传递 chunked,取决于三个协同条件:
-
上游必须返回合法的 HTTP/1.1 chunked 响应:即含
Transfer-Encoding: chunked头,且不含Content-Length;同时不能是 HTTP/1.0 响应 -
Nginx 必须与上游协商 HTTP/1.1:需显式配置
proxy_http_version 1.1;,否则默认用 HTTP/1.0,而该协议不支持 chunked -
不能触发 Nginx 自动计算并覆盖响应长度:只要
proxy_buffering on(默认值),Nginx 就会收完整个响应体,算出长度,删掉Transfer-Encoding,加上Content-Length后转发
负载均衡场景下必须调整的核心配置
在 upstream + proxy_pass 架构中,仅定义服务器组还不够,以下指令需写入对应 location 块内(非 upstream 块):
-
proxy_http_version 1.1;:强制升级到 HTTP/1.1,保障 chunked 语义有效 -
proxy_buffering off;:禁用响应体缓冲,使 Nginx 边收边发,避免长度重写 -
proxy_set_header Connection '';:清空上游可能带入的Connection: close等干扰头,防止连接提前终止 -
proxy_buffer_size 4k;(可选):缩小 header 缓冲区,降低首包延迟,也减少误判风险
注意:chunked_transfer_encoding on; 仅在 Nginx 自己作为源站生成流式响应时需要,代理模式下完全不用设,设了也无效。
为什么负载均衡后 chunked 消失了?常见原因
即使后端明确返回 chunked,客户端看到的却是 Content-Length,大概率是以下某一种情况:
- 未配
proxy_http_version 1.1;,Nginx 回退到 HTTP/1.0,自动禁用 chunked 并加Connection: close -
proxy_buffering仍为on(默认),Nginx 收完全部响应才转发,自然改写为定长 - 后端响应里同时存在
Content-Length和Transfer-Encoding: chunked(违反 HTTP 规范),Nginx 优先信任Content-Length并丢弃 chunked - 启用了
gzip on但没配gzip_vary on,压缩后长度固定,导致 Nginx 强制添加Content-Length
验证是否真正启用 chunked 透传
不能只看响应头有没有 Transfer-Encoding: chunked,要确认数据是否真的分块流动:
- 用
curl -v http://your-domain/观察原始响应流,留意是否有类似1a\r\n...、0\r\n\r\n这样的 chunk size 行 - 浏览器 DevTools → Network → Response → Headers 查看是否含
Transfer-Encoding: chunked,且无Content-Length - 检查 Nginx error log,出现
upstream sent no valid HTTP/1.1 header提示,说明上游协议不合规或版本不匹配 - 若用于 SSE 或流式日志,可配合
proxy_read_timeout 300;防止超时中断长连接











