You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot应用缓存控制配置问题:公共资源缓存及敏感数据禁缓存

我来帮你一步步解决这个问题。你现在能看到304响应但看不到Cache-Control头,主要是因为当前配置没区分开静态资源和敏感内容的缓存策略,而且Spring Security可能覆盖了Spring Boot默认的资源缓存头。下面是具体的解决方案:

1. 补全Spring Boot静态资源缓存配置

首先在application.properties(或application.yml)里完善静态资源的缓存规则,明确指定缓存时长和公开属性:

# 保留你的原有配置
spring.main.banner-mode=off
spring.main.log-startup-info=false

# 静态资源缓存配置:缓存一周(604800秒)
spring.resources.cache.cachecontrol.max-age=604800s
spring.resources.cache.cachecontrol.public=true
# 静态资源路径(默认已包含classpath:/static/、classpath:/public/等,可按需补充)
spring.resources.static-locations=classpath:/static/,classpath:/public/

2. 配置Spring Security区分缓存策略

光靠Spring Boot的资源配置还不够,因为Spring Security会对所有请求的响应头做统一处理,所以需要在Security配置里针对静态资源和敏感内容分别设置Cache-Control头:

如果你用的是Spring Boot 2.7及以下(WebSecurityConfigurerAdapter未弃用):

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.header.writers.CacheControlHeadersWriter;
import org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 允许静态资源无需认证即可访问
        http.authorizeRequests()
                .antMatchers("/images/**", "/js/**", "/css/**").permitAll()
                .anyRequest().authenticated();

        // 配置静态资源的缓存头:公开缓存,有效期一周
        CacheControlHeadersWriter staticCacheWriter = new CacheControlHeadersWriter();
        staticCacheWriter.setCacheControl("public, max-age=604800");

        // 配置敏感内容的缓存头:禁止缓存
        CacheControlHeadersWriter sensitiveCacheWriter = new CacheControlHeadersWriter();
        sensitiveCacheWriter.setCacheControl("no-cache, no-store, must-revalidate");

        // 给不同路径绑定对应的缓存头
        http.headers()
                .addHeaderWriter(new DelegatingRequestMatcherHeaderWriter(
                        new OrRequestMatcher(
                                new AntPathRequestMatcher("/images/**"),
                                new AntPathRequestMatcher("/js/**"),
                                new AntPathRequestMatcher("/css/**")
                        ),
                        staticCacheWriter
                ))
                .addHeaderWriter(new DelegatingRequestMatcherHeaderWriter(
                        new NegatedRequestMatcher(new OrRequestMatcher(
                                new AntPathRequestMatcher("/images/**"),
                                new AntPathRequestMatcher("/js/**"),
                                new AntPathRequestMatcher("/css/**")
                        )),
                        sensitiveCacheWriter
                ));
    }
}

如果你用的是Spring Boot 2.7+(推荐使用SecurityFilterChain):

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.header.writers.CacheControlHeadersWriter;
import org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 配置权限规则:静态资源放行,其他请求需认证
        http.authorizeRequests(auth -> auth
                .antMatchers("/images/**", "/js/**", "/css/**").permitAll()
                .anyRequest().authenticated()
        );

        // 静态资源缓存策略
        CacheControlHeadersWriter staticCacheWriter = new CacheControlHeadersWriter();
        staticCacheWriter.setCacheControl("public, max-age=604800");

        // 敏感内容缓存策略
        CacheControlHeadersWriter sensitiveCacheWriter = new CacheControlHeadersWriter();
        sensitiveCacheWriter.setCacheControl("no-cache, no-store, must-revalidate");

        // 绑定路径与缓存头
        http.headers(headers -> headers
                .addHeaderWriter(new DelegatingRequestMatcherHeaderWriter(
                        new OrRequestMatcher(
                                new AntPathRequestMatcher("/images/**"),
                                new AntPathRequestMatcher("/js/**"),
                                new AntPathRequestMatcher("/css/**")
                        ),
                        staticCacheWriter
                ))
                .addHeaderWriter(new DelegatingRequestMatcherHeaderWriter(
                        new NegatedRequestMatcher(new OrRequestMatcher(
                                new AntPathRequestMatcher("/images/**"),
                                new AntPathRequestMatcher("/js/**"),
                                new AntPathRequestMatcher("/css/**")
                        )),
                        sensitiveCacheWriter
                ))
        );

        return http.build();
    }
}

3. 验证配置效果

配置完成后重启应用,在Chrome网络面板中:

  • 访问静态资源(比如/images/logo.png),正常刷新页面(不要用Ctrl+F5强制刷新),查看响应头应该能看到Cache-Control: public, max-age=604800;
  • 访问敏感接口(比如用户信息接口),响应头会显示Cache-Control: no-cache, no-store, must-revalidate;
  • 304响应是协商缓存的正常表现,它和Cache-Control强制缓存可以共存,浏览器会优先遵循Cache-Control的规则。

为什么之前看不到Cache-Control头?

主要是因为Spring Security的默认配置会对所有响应的缓存头做限制,覆盖了Spring Boot的资源缓存配置。通过上面的配置,我们明确给不同路径指定了对应的缓存策略,就能让响应头正确输出了。

内容的提问来源于stack exchange,提问作者vibetribe93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:27:45