Nginx静态资源返回400错误大概率因请求头过大被拦截,需先查error.log确认“client sent too large header”等提示,再调大client_header_buffer_size(如8k)和large_client_header_buffers(如4 16k),并优先通过独立域名隔离静态资源以根治Cookie膨胀问题。

静态资源(如 CSS、JS、图片)加载时突然返回 400 错误,但文件本身存在、后端无异常,大概率是 Nginx 在解析请求头阶段就拒绝了请求——根源常为 large_client_header_buffers 不足,尤其当 Cookie 或自定义 Header 过长时。
先确认是不是它在报错
别急着改配置,先定位问题:
- 查 Nginx
error_log,搜索"request header or cookie too large"或"client sent too large header",重点关注静态路径(如/app.js、/style.css) - 用
curl模拟超长 Cookie:curl -H "Cookie: $(python3 -c 'print(\"sid=123;\" + \"a=\" + \"x\"*10000)')" https://yoursite.com/app.js,看是否稳定复现 400 - 打开浏览器 Network 面板,选中失败的静态请求,展开 Request Headers,手动估算 Cookie 字符串长度(注意 URL 编码会增加约 30%)
合理调整 large_client_header_buffers
这个指令控制 Nginx 可分配的“大缓冲区”数量和单个大小,只影响请求行和请求头(不涉及请求体),必须配合 client_header_buffer_size 使用:
- 典型安全值:设为
large_client_header_buffers 4 16k,即最多 4 个缓冲区,每个最大 16KB;能覆盖绝大多数含多段 JWT、SSO Token 和 A/B 标识的场景 - 若实测最大 Cookie 接近 12KB,建议单 buffer ≥ 16k,数量 ≥ 2(因还需容纳 Host、Referer 等其他头部)
- 不要盲目设成
16 64k——总上限达 1MB,易被用于 DoS 攻击,也浪费 worker 内存 - 该指令可放在
http、server或精准的location ~* \.(js|css|png|jpg|gif|ico)$块中;优先放在server块,避免全局放宽
必须同步配 client_header_buffer_size
large_client_header_buffers 是“后备方案”,能否触发取决于初始缓冲区是否溢出:
- 必须设
client_header_buffer_size 8k(或至少 4k),且该值 ≤large_client_header_buffers中的单个 buffer 大小(如 8k ≤ 16k) - 如果设成
client_header_buffer_size 32k但large_client_header_buffers 4 16k,Nginx 启动会报错,因为初始缓冲已大于单个大缓冲 - 推荐组合:
client_header_buffer_size 8k;+large_client_header_buffers 4 16k;
更可持续的源头优化
调大缓冲区是快速止血,但长期应减少请求头体积:
- 静态资源走独立域名(如
static.example.com),禁用 Cookie 共享,彻底消除 Cookie 传输 - 将长 Token 改用 JWT 并精简 payload,或转存至
localStorage,前端通过AuthorizationHeader 发送(可控长度) - 服务端清理过期/冗余 Cookie,避免多个 SSO 域名、埋点参数、实验 ID 拼接堆积
- 检查是否误将调试用 Header(如
X-Debug-Trace)随所有请求发出










