Nginx 默认不缓存 POST 请求,但可安全启用:需配置 proxy_cache_methods 包含 GET HEAD POST、自定义 proxy_cache_key 含 $request_body 或签名头、显式设置 proxy_cache_valid 支持 200/201 状态码。

Nginx 默认不缓存 POST 请求,因为这类请求通常具有副作用(如提交数据、修改状态),直接缓存可能引发重复执行、数据错乱或安全问题。但如果你确认某个 POST 接口是幂等、只读、无用户私有数据的(比如搜索 API、GraphQL 查询、参数复杂的表单查询),就可以安全启用其响应缓存。
关键不是“能不能开”,而是“怎么开得稳、分得清、控得住”。
✅ 必须配置的三项核心指令
-
显式允许 POST 方法参与缓存
在location块中加入:proxy_cache_methods GET HEAD POST;
注意:仅写
POST不够,必须包含GET和HEAD(Nginx 要求至少两个方法);该指令需放在启用proxy_cache的上下文中。 -
自定义 cache key,确保不同 POST 内容不混用
默认 key(如$scheme$proxy_host$request_uri)对所有 POST 请求都一样,会导致缓存污染。应加入能区分请求体的变量:proxy_cache_key "$scheme$proxy_host$request_uri$args$request_body";
⚠️ 前提:
$request_body必须可用——需保证client_max_body_size合理、proxy_buffering on(默认开启)、且请求体未被流式读取跳过。更稳妥替代方案(推荐用于生产):
- 让后端将请求参数签名后写入自定义 header(如
X-Req-Sign: abc123),再在 key 中使用$http_x_req_sign; - 或改用 GET + query string(语义清晰、Nginx 原生支持、调试简单)。
- 让后端将请求参数签名后写入自定义 header(如
-
明确声明可缓存的状态码与有效期
proxy_cache_valid 200 201 60s;
如果 POST 返回的是
200 OK,就必须在这里显式覆盖,否则即使加了POST方法也不会缓存。
⚙️ 配套必须检查的配置项
-
忽略干扰响应头
后端若返回Cache-Control: no-cache或Set-Cookie,Nginx 默认跳过缓存。如你已确认安全,可忽略:proxy_ignore_headers Cache-Control Expires Set-Cookie;
-
启用 stale 策略提升并发体验
防止多个相同 POST 请求同时穿透回源:proxy_cache_use_stale updating;
-
限制缓存范围,避免误伤
不要在location /全局启用,而应精准匹配路径:location /api/search { proxy_cache my_cache; proxy_cache_methods GET HEAD POST; # …其他配置 } -
禁用含敏感信息的请求缓存
自动排除带 Cookie 或认证头的请求:proxy_no_cache $http_cookie $http_authorization;
? 如何验证是否生效
-
添加响应头便于观察:
add_header X-Cache-Status $upstream_cache_status always;
成功缓存后,响应头会出现
X-Cache-Status: HIT。 -
使用 curl 多次调用同一 POST 请求:
curl -X POST -d '{"q":"nginx"}' -H "Content-Type: application/json" http://your.site/api/search观察:
→ 响应时间明显下降;
→ 后端 access log 中只记录第一次请求;
→ Nginx error log 无cache lock相关警告(说明proxy_cache_lock配置合理)。
不复杂但容易忽略。


















