单设 proxy_buffer_size 不够,因其仅控制 Nginx 接收后端响应头的缓冲区,对客户端请求头无效;需协同调整 client_header_buffer_size 和 large_client_header_buffers 等参数。

要让 Nginx 正确处理携带超长 JWT Token 的 WebSocket 握手请求(如 Sec-WebSocket-Protocol 或自定义头中含长 Base64 Token),关键不是只调大 proxy_buffer_size,而是协同调整多个缓冲区参数,确保整个 HTTP 请求头(包括 Upgrade 请求行、所有 headers)能被完整读入、透传。
为什么单设 proxy_buffer_size 不够?
proxy_buffer_size 仅控制 Nginx 从上游(如后端 WebSocket 服务)读取响应头时的缓冲区大小,**对客户端发来的请求头完全无效**。WebSocket 握手是客户端 → Nginx → 后端的请求流程,真正影响握手失败的是 Nginx 接收客户端请求头的能力。
常见报错如 400 Bad Request、414 Request-URI Too Long(误报,实为 header 超限)或连接直接中断,往往源于以下任一限制被触发:
-
client_header_buffer_size:存储初始请求行和短 header 的小缓冲区(默认 1k) -
large_client_header_buffers:当 header 超出client_header_buffer_size时,Nginx 尝试用此配置分配更大缓冲区(默认 4 × 8k) -
client_max_body_size:虽不直接影响 header,但某些带 Token 的协议(如自定义认证头)若误走 body 路径会受其限制
核心配置项与推荐值
在 http 或对应 server 块中设置:
1. 提升请求头接收能力
假设最长 Token + 其他 headers 总长预估 ≤ 16KB:
-
client_header_buffer_size 2k;(可选微增,非必须) -
large_client_header_buffers 4 16k;(关键!4 个缓冲区,每个 16KB,总容量 64KB)
2. 确保 WebSocket 升级请求不被拦截
添加显式支持,避免因 header 过长被中间逻辑拒绝:
-
underscores_in_headers on;(若 Token 放在含下划线的自定义头中,如X-Auth-Token) -
ignore_invalid_headers off;(确保非法字符头不被静默丢弃,便于调试)
3. 透传关键 header 给后端(proxy 配置段内)
在 location /ws/ { ... } 中确保:
proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;- —— 若 Token 在
Authorization或Sec-WebSocket-Protocol中,无需额外 set_header,Nginx 默认透传
验证与调试方法
配置后务必验证是否生效:
- 用
curl -v -H "Sec-WebSocket-Protocol: $(python3 -c 'print(\"A\"*12000)')" http://your-domain.com/ws模拟长 header 握手 - 检查 Nginx error log:
tail -f /var/log/nginx/error.log,关注client sent too large header类错误 - 确认后端实际收到的 header 长度(如 Node.js 的
req.headers['sec-websocket-protocol'].length) - 临时开启
debug日志级别(需编译含 debug 模块)可精确定位卡在哪个缓冲阶段
补充说明:proxy_buffer_size 的真实作用
该指令仅在 Nginx 作为反向代理、接收后端返回的 响应头 时起作用。例如后端在 WebSocket 升级后的响应中附带超长 Set-Cookie 或自定义响应头,才需要它。对于客户端发起的握手请求,它完全不参与处理。误配它不会导致握手失败,但可能影响后续响应解析。











