Nginx缓存失效的根源在于后端主动返回no-cache、no-store、max-age=0等禁用缓存的响应头,导致proxy_cache跳过缓存;需检查真实响应头并覆盖或修正后端配置。

根本问题不是 Nginx 没缓存,而是后端(Java 或 PHP 应用)主动告诉 Nginx“别缓存我”——通过返回 Cache-Control: no-cache、no-store、max-age=0 或缺失 Expires 等响应头,导致 Nginx 默认跳过缓存逻辑。即使你配了 proxy_cache,只要后端头不配合,缓存率就是 0%。
确认是否真被后端头干扰
先抓一个真实请求的响应头(如访问 /api/user 或静态资源路径),重点检查:
-
Cache-Control值是否含no-cache、no-store、must-revalidate或max-age=0 -
Expires是否为过去时间(如Expires: Wed, 01 Jan 1970 00:00:00 GMT) -
Vary是否过于宽泛(如Vary: *或含动态字段如Vary: Cookie, User-Agent)
若存在上述任一情况,Nginx 就不会缓存该响应(除非显式覆盖)。
Java 应用(如 Spring Boot / Tomcat)常见误配点
Spring Boot 默认对所有 controller 响应加 Cache-Control: no-cache;Tomcat 的默认 servlet 对 JSP/静态资源也可能返回弱缓存策略。
立即学习“PHP免费学习笔记(深入)”;
- Spring Boot 中全局禁用:在
application.properties加server.tomcat.background-processor-delay=10不起作用,真正有效的是配置 WebMvcConfigurer:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/")
.setCachePeriod(31536000); // 强制设为 1 年
}
}
- 对 API 接口,避免在 Controller 方法里写
response.setHeader("Cache-Control", "no-cache") - Tomcat 的
web.xml中,检查<session-config>下是否设置了<cookie-http-only>或<secure-cookie>导致隐式添加Vary: Cookie
PHP 应用(如 ThinkPHP、Laravel)典型原因
PHP 脚本常在入口或中间件中调用 header('Cache-Control: no-cache, private'),尤其登录态、调试模式下默认关闭缓存。
- ThinkPHP:检查
config/cache.php中'default' => 'file'是缓存驱动,但页面级缓存需手动开启;更关键的是查看app/middleware.php或中间件类里是否有header()强制设置 - Laravel:确认
App\Http\Middleware\PreventRequestsDuringMaintenance或自定义中间件未注入Cache-Control头;运行php artisan config:clear后仍无效,说明是运行时 header 写入 - 通用排查:在 PHP 文件最顶部加
header_remove('Cache-Control');+header('Cache-Control: public, max-age=3600');临时验证是否生效
Nginx 层强制接管缓存策略(慎用)
当无法修改后端代码时,可在 Nginx 的 location 块中覆盖响应头,但仅适用于内容稳定、无用户状态依赖的接口或资源:
- 清除后端传来的干扰头:
proxy_hide_header Cache-Control;、proxy_hide_header Expires;、proxy_hide_header Vary; - 重写缓存策略:
add_header Cache-Control "public, max-age=3600" always;(always确保对 2xx/3xx 都生效) - 配合缓存区启用:
proxy_cache_valid 200 302 1h;、proxy_cache_use_stale error timeout updating; - 注意:若后端返回
Set-Cookie,Nginx 默认不缓存(因含用户数据),此时需加proxy_ignore_headers Set-Cookie;—— 仅限无敏感状态的场景
不复杂但容易忽略


















