Nginx默认不压缩已压缩二进制文件,但误配gzip_types(如加入image/jpeg)或未排除application/octet-stream会导致错误压缩;应仅保留文本类MIME,确保Content-Type与mime.types一致,并在预压缩时仅启用gzip_static on。

Nginx 默认就不会对图片、视频等已压缩的二进制文件做 Gzip 压缩,前提是配置得当。问题往往出在人为误配——比如在 gzip_types 里加了 image/jpeg 或 video/mp4,或者没关掉动态压缩却还期望前端预压缩生效。
关键不是“Nginx 怎么处理”,而是你怎么告诉 Nginx 别去碰它们。
明确排除已压缩的二进制类型
gzip_types 只看响应头里的 Content-Type,不看文件后缀。它默认只压 text/html,一旦你自定义了 gzip_types,就会完全覆盖默认行为——所以既要写全该压的,也要确保不写不该压的:
- ✅ 必须包含:
text/html text/plain text/css application/javascript application/json text/xml application/xml+rss image/svg+xml - ❌ 绝对禁止加入:
-
image/jpeg、image/png、image/gif、image/webp、image/avif -
video/mp4、video/webm、audio/mpeg -
application/zip、application/pdf、application/x-rar-compressed -
application/octet-stream(这是万能兜底类型,极易误伤)
-
注意:
image/svg+xml是例外,它是纯文本 XML 格式,应当且必须压缩。
确保 MIME 类型真实匹配
即使你没在 gzip_types 里写 image/jpeg,如果某张 PNG 图片因为 MIME 配置缺失,被 Nginx 错标为 application/octet-stream,而你又不小心把 application/octet-stream 加进了 gzip_types,那它就会被强行压缩——不仅白耗 CPU,还可能让体积变大。
检查方法:
curl -I https://yoursite.com/static/logo.png
看响应头中 Content-Type 是否为 image/png。如果不是,就去 /etc/nginx/mime.types(或对应路径)补上:
types {
image/png png;
image/webp webp;
video/mp4 mp4;
}静态资源预压缩时,彻底关闭动态压缩
如果你用 Webpack/Vite 提前生成了 .js.gz、.css.gz,那就该让 Nginx 只走静态路径,不碰实时压缩:
- 删除或注释所有
gzip on及相关指令(如gzip_comp_level、gzip_min_length) - 只保留一行:
gzip_static on; - 确保
.gz文件与原始文件权限一致、同目录、同名(如app.js对应app.js.gz)
这样,请求 app.js 时,Nginx 找到 app.js.gz 就直接返回,并自动加 Content-Encoding: gzip;找不到就回退发原始 app.js(不压缩),安全又高效。
小结一下操作要点
- 不要相信“默认不压图片”就高枕无忧,
gzip_types一错,全盘失效 -
gzip_types里只列明确需要压缩的文本类 MIME,一个已压缩格式都别加 - 检查实际响应头的
Content-Type,和mime.types、gzip_types三者必须一致 - 预压缩场景下,
gzip on和gzip_static on不能共存,否则逻辑冲突
不复杂但容易忽略。


















