nginx 默认不缓存非 get 请求,要严格只缓存 get/head,需显式配置 fastcgi_cache_methods get head,并检查 fastcgi_cache_bypass、fastcgi_no_cache 及 map 规则是否正确生效,同时对敏感路径禁用缓存。

Nginx 默认就不缓存非 GET 请求,所以“排除非 GET 请求缓存”其实是它的安全默认行为,不需要额外操作。但如果你之前改过 fastcgi_cache_methods、现在想恢复严格只缓存 GET/HEAD,关键不是“排除”,而是显式限定、并清除干扰项。
只允许 GET 和 HEAD 缓存
在启用 fastcgi_cache 的 location 块中,明确写死方法列表:
fastcgi_cache_methods GET HEAD;
这条指令必须存在,且不能被其他配置覆盖(比如 fastcgi_no_cache 或 fastcgi_cache_bypass 设为非空值)。只要它生效,POST、PUT、DELETE 等一律不会进入缓存——Nginx 会在请求阶段直接跳过缓存逻辑。
确保没有意外放行非 GET 请求
常见导致非 GET 请求“误入缓存”的原因有三个,需逐个检查:
fastcgi_cache_methods被错误扩展
比如写了GET HEAD POST却忘了删掉POST,或继承自上级块。搜索整个配置确认只有一处fastcgi_cache_methods,且值仅为GET HEAD。-
fastcgi_cache_bypass或fastcgi_no_cache配置失效
这两个指令若设为0、空字符串或未定义变量,可能失去拦截作用。稳妥做法是主动用变量控制:set $skip_cache 0; if ($request_method != GET) { set $skip_cache 1; } if ($request_method != HEAD) { set $skip_cache 1; } fastcgi_no_cache $skip_cache; fastcgi_cache_bypass $skip_cache;⚠️ 注意:
if在location内可用,但不推荐在server或http级别使用;更优解是用map(见下一条)。 -
用了
map但没配合fastcgi_cache_bypass
推荐用map显式标记危险方法:map $request_method $no_cache { POST 1; PUT 1; DELETE 1; PATCH 1; default 0; }然后在 location 中启用:
fastcgi_cache_bypass $no_cache; fastcgi_no_cache $no_cache;
对敏感路径做双重保险
即使方法层面已限制,仍建议对提交类、管理类路径直接关缓存:
location ~ ^/(api/v1/submit|admin|login|logout|webhook) {
fastcgi_cache off;
# 或者直接 proxy_pass + 不配 cache 指令
}
这样即使某处漏配 fastcgi_cache_methods,这些路径也绝不会缓存。
验证是否真正排除成功
加一行响应头方便调试:
add_header X-Cache-Status $upstream_cache_status;
发起一个 POST 请求,查看响应头:
- 如果看到
X-Cache-Status: MISS或BYPASS,说明没进缓存 ✅ - 如果看到
HIT,说明仍有配置在放行,需回溯上述三点
不复杂但容易忽略











