nginx默认不缓存自身生成的return 301或rewrite permanent响应,因其绕过proxy_cache流程;真正可缓存的是后端返回的301/302响应,须显式配置proxy_cache_valid 301 7d和302 2m,并确保location匹配、忽略cache-control干扰、cache_key包含关键变量。

Nginx 默认不缓存由自身生成的 return 301 或 rewrite ... permanent 这类重定向响应——它们在请求处理早期就结束流程,压根不经过 proxy_cache。真正能被缓存的,是后端服务(如 PHP、Node.js)返回的、带 Location 头的 301/302 响应,前提是配置得当。
必须分开配置 301 和 302 的缓存时长
301 表示永久迁移,浏览器和 CDN 会主动长期缓存;302 表示临时跳转,应短时间缓存,避免掩盖上游变化。Nginx 不会自动区分二者,必须显式用两行 proxy_cache_valid:
-
proxy_cache_valid 301 7d;—— 推荐设为 7 天,兼顾 SEO 权重传递与回滚灵活性 -
proxy_cache_valid 302 2m;—— 一般设 2~5 分钟,高频变动场景可缩至 30 秒 - 不能写成
proxy_cache_valid 301 302 1h;或依赖any规则,否则 301 可能被忽略或缓存过短
确保缓存真正生效的三个关键点
光写对状态码还不够,以下三点任一缺失都会导致缓存“看似配置了,实则没用”:
-
location 要覆盖原始请求路径:比如旧 URL 是
/a返回 301,配置就得放在location /a { ... }里,而不是只配在新地址的 location 中 -
处理后端 Cache-Control 干扰:若上游返回
Cache-Control: no-cache,需加proxy_ignore_headers Cache-Control; -
cache_key 要包含影响跳转的变量:例如重定向逻辑依赖
?id=123,就要确保proxy_cache_key包含$args,否则不同参数会共用一个缓存项
更高效的做法:把跳转逻辑“固化”进 Nginx
对于大量固定映射(如旧文章 ID → 新路径),优先用 map + return,而非让后端动态计算:
- 用
map预定义跳转关系,Nginx 启动时编译,无运行时开销 - 配合
return 301 $new_uri;,整个过程不查 location、不走 proxy_pass,CPU 几乎为零 - 这相当于把“是否跳转、跳去哪”的决策缓存在配置层,比缓存响应体更轻量、更可靠
不复杂但容易忽略。











