关键在于区分nginx收客户端与发后端的accept-encoding:前者决定nginx自身是否压缩响应(需开启gzip、设置gzip_types等),后者影响后端返回格式与缓存一致性,应显式设为"gzip"或"identity"避免问题。

关键在于区分两个方向:Nginx 收到客户端的 Accept-Encoding,和 Nginx 发给后端的 Accept-Encoding。两者作用不同,配置逻辑也不同。默认透传容易引发缓存膨胀、压缩不一致或 Range 请求失效等问题。
控制发往后端的 Accept-Encoding(代理请求头)
这是最常被忽略的一环。Nginx 默认会把客户端的 Accept-Encoding 头原样转发给上游服务,导致后端对不同用户返回不同压缩格式(如 br/gzip/none),影响缓存效率与响应一致性。
- 显式覆盖,统一建议 gzip:在
location或upstream块中添加proxy_set_header Accept-Encoding "gzip"; - 若后端明确支持 Brotli 且需启用,可写为:
proxy_set_header Accept-Encoding "br, gzip, deflate";(注意顺序代表优先级) - 禁用后端压缩(例如配合 Range 分块或中间代理):
proxy_set_header Accept-Encoding "identity";
控制客户端请求的 Accept-Encoding(影响 Nginx 自身压缩)
这部分决定 Nginx 是否对响应内容做 gzip 压缩,并返回 Content-Encoding: gzip。
- 确保已开启 gzip:
gzip on; - 只压缩合适类型:
gzip_types text/plain text/css application/json application/javascript text/xml application/xml+rss image/svg+xml; - 避免小文件得不偿失:
gzip_min_length 1024; - 让代理/CDN 知道响应可能被压缩:
gzip_vary on;
避免重复压缩与解压冲突
当 Nginx 同时作为压缩者(对客户端)和代理(对后端)时,必须防止双重处理:
- 关闭 Nginx 对后端响应的二次压缩:
gzip_proxied off;(默认值,但建议显式声明) - 若后端返回 gzip 响应,而你又希望 Nginx 解压后再处理(如修改响应体),启用:
gunzip on;(注意:仅支持 gzip,不支持 br) - 不推荐同时开启
gzip on和gunzip on处理同一类响应,易造成逻辑混乱
常见问题对应配置
某些场景下,Accept-Encoding 配置直接决定功能是否可用:
-
Range 请求失效:浏览器发
Range: bytes=0-1024,Nginx 返回压缩后的 206,下游代理无法分块转发 → 改用proxy_set_header Accept-Encoding "identity"; -
CDN 缓存爆炸:同一 URL 因
Accept-Encoding差异缓存多份 → 统一设为"gzip"并配gzip_vary on,让 CDN 按单一编码缓存 -
后端未响应压缩内容:确认后端已启用对应压缩中间件(如 Spring Boot 的
server.compression.enabled=true),且 MIME 类型匹配











