核心是让CDN回源时不带br或源站Nginx不响应br,推荐后者;通过map清空回源Accept-Encoding头、禁用brotli模块、分层控制终端与回源压缩,并验证配置生效。

核心是让 CDN 回源时“不带 br”,或源站 Nginx “不响应 br”——二者选一即可,推荐后者更稳妥。
统一回源压缩格式:只允许 gzip
CDN(如 Cloudflare、阿里云全站加速)回源常带 Accept-Encoding: br, gzip,但多数源站 Nginx 并未正确启用 Brotli,结果返回乱码或 500。最直接的解法是强制源站忽略 br 请求:
- 在
http块顶部添加map规则,清空回源请求的编码头:
map $http_user_agent $disable_br {
~*^(Cloudflare-nginx|AliyunSCDN|CDN|Edge) 1;
default 0;
}
map $disable_br $accept_encoding {
1 "";
0 $http_accept_encoding;
}
- 再在
server或location中使用:proxy_set_header Accept-Encoding $accept_encoding; - 这样 CDN 回源时头被清空,Nginx 只按默认逻辑处理(即只走 gzip)
彻底禁用 Brotli 回源响应
即使你编译了 Brotli 模块,也不必让它参与回源链路。关键是不让它对回源请求生效:
- 确认
brotli off;已写在http或server块中(部分版本支持该指令) - 若不支持
brotli off,可注释或删除所有brotli on、brotli_static on等相关行 - 同时检查是否加载了模块:
nginx -V 2>&1 | grep -o ngx_brotli,无输出则无需担心
保留 Brotli 给终端用户,隔离回源路径
想继续用 Brotli 加速真实用户访问?可以分层控制:
- 对来自公网的请求(含 UA、IP 段判断),正常启用
brotli on和gzip on - 对已知 CDN 回源 IP 段(如 Cloudflare 的 173.245.48.0/20),用
if ($remote_addr ~ "173\.245\.48\.[0-9]+") { set $bypass_brotli 1; } - 在
gzip_types和brotli_types后加条件判断,或通过add_header Vary "Accept-Encoding"配合缓存键分离
验证与兜底要点
配置改完必须验证,避免“看似生效实则失效”:
- 用
curl -H "Accept-Encoding: br" -I https://your-domain.com/test.js测试终端用户能否拿到 br - 模拟 CDN 回源:加
-H "User-Agent: Cloudflare-nginx",确认响应头不含Content-Encoding: br - 确保
gzip_vary on;开启,防止 CDN 缓存错版本 - 静态资源建议预生成
.br和.gz文件,启用gzip_static on;和brotli_static on;,减少运行时开销


















