http方法不直接决定缓存,但可通过nginx的map指令映射请求方法为变量,结合proxy_cache_bypass、proxy_cache_key等实现按方法差异化缓存与回源分流,如仅缓存get/head、绕过post/put/delete,并支持按方法路由至不同上游。

HTTP 方法本身不直接决定缓存行为,但可以通过 map 指令在 Nginx 中将请求方法映射为变量,再结合 proxy_cache_bypass、proxy_no_cache 和 proxy_cache_key 等指令,实现“按方法差异化缓存”与“回源分流”。这不是标准缓存策略,而是基于业务语义的主动控制——比如只缓存 GET 和 HEAD,强制跳过 POST/PUT/DELETE 的缓存,并让这些请求直连后端或路由到特定上游。
用 map 定义缓存开关变量
在 http 块中定义一个映射,把请求方法转为是否启用缓存的布尔值(0/1)或缓存区域名:
map $request_method $cache_bypass {
default 1; # 默认绕过缓存(安全起见)
GET 0;
HEAD 0;
OPTIONS 0;
}这个变量后续可用于 proxy_cache_bypass:值为非空且非 0 时,Nginx 不查缓存、直接回源。
按方法设置不同缓存键与缓存区
更精细的做法是,不仅控制“是否缓存”,还控制“缓存存哪、怎么算唯一性”:
map $request_method $cache_zone {
GET static_cache;
HEAD static_cache;
POST api_no_cache; # 指向一个 TTL=0 的 zone,或干脆不配置
default api_no_cache;
}
<p>map $request_method $cache_key {
GET "$scheme$request_method$host$request_uri";
HEAD "$scheme$request_method$host$request_uri";
POST "$scheme$request_method$host$request_uri$request_body"; # 含 body,适合幂等 POST
default "$scheme$request_method$host$request_uri";
}</p>然后在 location 中使用:
proxy_cache $cache_zone;proxy_cache_key $cache_key;-
proxy_cache_bypass $cache_bypass;(配合前面的 map)
结合 upstream 实现方法级回源分流
若需让不同方法走不同后端(如 GET 走 CDN 回源集群,POST 走强一致性主库 API),可进一步用 map 控制 proxy_pass:
map $request_method $backend {
GET http://cdn-upstream;
HEAD http://cdn-upstream;
POST http://api-primary;
PUT http://api-primary;
DELETE http://api-primary;
}
<p>server {
location /api/ {
proxy_pass $backend;
proxy_cache $cache_zone;
proxy_cache_bypass $cache_bypass;</p><h1>其他缓存头设置...</h1><pre class="brush:php;toolbar:false;">}}
注意:proxy_pass 后不能带 URI 路径时才支持变量;若需路径重写,应改用 rewrite + if 或 Lua(但 if 在 location 中有陷阱,慎用)。
关键注意事项
-
POST、PUT等方法默认不被缓存,即使配置了proxy_cache也需显式启用proxy_cache_methods POST; -
$request_body在map中不可用(Nginx 读取 body 在 rewrite 阶段之后),如需基于 body 缓存,必须用lua-resty-redis或 OpenResty 的access_by_lua_block -
OPTIONS请求常用于 CORS 预检,建议单独缓存(短 TTL),避免压垮后端 - 所有
map必须定义在http块顶层,不能嵌套在server或location内











