nginx对cdn回源响应启用gzip压缩需配置gzip_proxied而非仅gzip on,因默认跳过含via头的代理响应;推荐值为expired no-cache no-store private auth,并配合proxy_hide_header content-encoding、gzip_vary on及关闭后端压缩。

要让 Nginx 在反向代理(尤其是 CDN 回源)场景下对后端响应启用 Gzip 压缩,关键不是只开 gzip on,而是必须用 gzip_proxied 显式接管压缩决策权。默认情况下,Nginx 遇到带 Via 头的代理请求(如 CDN 回源)会跳过压缩,哪怕其他 gzip 配置全开也无效。
为什么需要显式配置 gzip_proxied
Nginx 默认将含 Via 请求头的流量识别为代理链路,并按 gzip_proxied off 处理——即彻底禁用对上游响应体的压缩。CDN(如阿里云、腾讯云)回源必带 Via,这就导致未压缩的原始响应直接透传,白白增加回源带宽和延迟。
- 它不控制 Nginx 自身生成的响应,只作用于
proxy_pass转发后收到的上游响应体 - 仅在
gzip on已启用的前提下才生效,二者缺一不可 - 它的值不是开关,而是一组响应头匹配规则,满足任一即触发压缩
推荐的 gzip_proxied 值组合
生产环境最稳妥且覆盖多数动态内容的写法是:
gzip_proxied expired no-cache no-store private auth;
这个组合精准对应常见回源响应特征:
-
expired:后端返回了
Expires且时间已过期 → 适合 CDN 缓存失效后需刷新的内容 -
no-cache / no-store:响应含
Cache-Control: no-cache或no-store→ 表明不可缓存,但体积常大(如动态 JS/CSS),压缩安全 -
private:含
Cache-Control: private→ 用户专属数据(如登录态接口),压缩可降带宽又不破坏语义 -
auth:请求头含
Authorization→ 鉴权后响应通常敏感且未压缩,压缩合理
避免使用 any,它无条件压缩所有代理响应,可能对图片、视频等已压缩资源造成二次压缩乱码或体积增大。
配套必须做的几件事
光配 gzip_proxied 不够,还需同步处理三个关键点:
-
剥离上游误设的 Content-Encoding:在
location或upstream块中加proxy_hide_header Content-Encoding;,防止后端错误返回该头导致 Nginx 跳过压缩 -
开启 gzip_vary:加上
gzip_vary on;,让 CDN 或浏览器知道响应是否依赖Accept-Encoding,避免缓存错乱 -
确认上游不自行压缩:建议后端关闭 Gzip(如 Express 的
compression()中间件),统一由 Nginx 层集中处理——更可控、易调优、防嵌套异常
如何验证是否生效
别只看配置,用真实请求验证:
- 执行:
curl -H "Accept-Encoding: gzip" -I https://your-domain.com/api/data - 检查响应头是否含
Content-Encoding: gzip和Vary: Accept-Encoding - 对比绕过 Nginx 直连后端的响应头,确认是 Nginx 在压缩而非后端
- 查 access log 中
$gzip_ratio变量:非破折号(-)表示已压缩,数值越接近 1.0 压缩率越高











