nginx 通过 gzip_http_version 1.1 指令限制仅对 http/1.1 及以上协议请求启用 gzip 压缩,自动排除 http/1.0 请求,配合 host 头校验可进一步提升安全性与兼容性。

Nginx 本身不支持“按 HTTP 协议版本(如 HTTP/1.0、HTTP/1.1)直接开启或关闭 gzip 压缩”,因为 gzip 是响应级功能,其触发取决于客户端请求头(如 Accept-Encoding)、响应内容类型(Content-Type)、大小(Content-Length)等,而非请求行中的协议字段(如 GET / HTTP/1.0 中的 HTTP/1.0)。
但你真正想实现的,通常是:
✅ 避免对低版本协议(尤其是 HTTP/1.0)请求启用 gzip,因其常伴随无 Host 头、无持久连接、不可靠客户端等风险,压缩收益低且可能引入兼容性或资源消耗问题。
❌ 不是“识别并过滤协议字符串”,而是在协议不满足基本安全/规范前提下,主动跳过压缩逻辑。
以下是符合生产实践、稳定可控的配置方式:
显式限制 gzip 生效的最低 HTTP 版本
使用 gzip_http_version 指令,它控制 Nginx 仅对指定版本及以上协议的请求响应启用 gzip:
http {
gzip on;
gzip_http_version 1.1; # ← 关键:只对 HTTP/1.1 及以上请求启用压缩
gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;
gzip_min_length 20;
}
-
gzip_http_version 1.1表示:只有当$server_protocol的值为HTTP/1.1或HTTP/2(Nginx 内部将 HTTP/2 视为兼容 1.1+)时,才考虑执行压缩。 - HTTP/1.0 请求(如
GET / HTTP/1.0)会被自动排除在 gzip 流程之外,即使它带了Accept-Encoding: gzip。 - 此指令作用于整个请求生命周期早期,无需
if、无性能损耗,是官方推荐方式。
配合 Host 头校验,进一步筛掉典型 HTTP/1.0 流量
绝大多数真实 HTTP/1.0 客户端(尤其恶意扫描器或老旧工具)不会发送 Host 头。你可以用它作为代理指标,在无 Host 时直接禁用 gzip(或返回 400):
server {
listen 80;
server_name _;
# 若 Host 头缺失,视为非标准/不可信请求,跳过压缩
if ($host = "") {
set $no_gzip "1";
}
location / {
gzip off;
if ($no_gzip != "1") {
gzip on;
}
# 其他 proxy_pass 或静态服务配置
}
}
⚠️ 注意:if 在 location 内有限可用,此写法仅适用于简单场景;更推荐用 gzip_http_version 1.1 主控 + if ($host = "") { return 400; } 辅助拦截,双保险。
不要做的误区
- ❌ 不要用
map或正则匹配$request_line提取HTTP/1.0字符串 —— 协议字段未标准化解析,易被伪造,且 Nginx 不保证$request_line在所有阶段都可用。 - ❌ 不要在
if中嵌套gzip on/off到server级别 —— Nginx 官方明确不支持,会导致配置加载失败或行为未定义。 - ❌ 不要依赖
gzip_disable匹配 User-Agent 来间接过滤协议 —— 它针对浏览器 UA,与协议版本无直接关系,逻辑错位。
本质上,gzip_http_version 就是你需要的“忽略非标准 HTTP 协议请求”的最简洁、最可靠机制。它不是“过滤”,而是“条件准入”——让 gzip 只服务于现代、合规的协议交互。











