事情本身不复杂,线索都在日志里。Ubuntu 22.04 上 nginx 和上游的 Node 服务都开了 gzip,浏览器打开页面显示乱码,响应头里出现两个 Content-Encoding: gzip,curl 加 –compressed 才能正常解码。

第一反应是「gzip_proxied 配置让它对所有代理响应都做压缩,不看上游是否已经压过」,验证下来不成立。

这类报错背后常见的原因有几处,逐个排除就行。上游已经压缩过,nginx 又压了一次,响应头被重复写入导致解码失败。少数情况下是nginx 的 proxy_set_header 没有清掉上游的 Content-Encoding。

少数情况下是中间还有一层 CDN 也开了压缩,三层叠在一起。

上来先看响应头里编码出现了几次

curl -sI -H 'Accept-Encoding: gzip' https://www.example.com/ | grep -i content-encoding

只保留一侧压缩,源站交出控制权

printf 'gzip on;\ngzip_proxied any;\ngzip_types text/css application/javascript;\n' > /etc/nginx/conf.d/gzip.conf

然后关掉上游的压缩并重启应用

kubectl set env deploy node-web GZIP_ENABLED=false

末了用浏览器同款请求验证解码

curl -s --compressed -o /dev/null -w '%{http_code} %{size_download}\n' https://www.example.com/

恢复的判定其实很直接。响应头里只有一个 Content-Encoding,curl –compressed 返回 200 且页面内容正常,DevTools 里不再报解码错误。

压缩只能做一次,通常放在最外层;图片和视频不要进 gzip_types,既压不动又白耗 CPU。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189