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

Spring Boot REST API添加Content-Security-Policy头后遇CORS问题求助

解决Spring Boot跨域预检请求失败问题

你遇到的报错是CORS策略阻止请求,根源是浏览器发起跨域请求前的OPTIONS预检请求未被服务器正确响应,和你配置的X-Content-Security-Policy响应头无关。Swagger调用正常是因为Swagger页面和API服务同域,不会触发跨域检查;而本地UI(http://localhost:4200)和API服务端口不同,属于跨域请求,浏览器会先发送OPTIONS预检请求验证服务器是否允许跨域,你的服务当前没有处理这个请求,导致报错。

方案一:全局配置CORS(推荐)

修改你的WebSecurityConfig,添加CORS配置,确保OPTIONS请求被正确处理:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // 启用CORS配置
            .cors().and()
            // 禁用CSRF(按需调整,若业务需要CSRF可保留并配置放行规则)
            .csrf().disable()
            // 其他原有配置
            .headers()
                .addHeaderWriter(new StaticHeadersWriter("X-Content-Security-Policy","script-src 'self'"));
    }

    // 定义CORS规则
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        // 允许本地UI的跨域请求,生产环境请替换为实际前端域名
        config.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
        // 允许的HTTP请求方法
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        // 允许所有请求头
        config.setAllowedHeaders(Arrays.asList("*"));
        // 允许携带Cookie等凭证(按需开启)
        config.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 对所有API路径应用CORS规则
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

适配Spring Boot 2.7+版本(WebSecurityConfigurerAdapter已弃用)

如果你的Spring Boot版本是2.7及以上,使用SecurityFilterChain替代WebSecurityConfigurerAdapter:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .cors(cors -> cors.configurationSource(corsConfigurationSource()))
            .csrf(csrf -> csrf.disable())
            .headers(headers -> headers
                .addHeaderWriter(new StaticHeadersWriter("X-Content-Security-Policy","script-src 'self'"))
            );
        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        config.setAllowedHeaders(Arrays.asList("*"));
        config.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

方案二:局部接口配置CORS

如果只需要给特定接口开启跨域,可在Controller类或方法上添加@CrossOrigin注解:

@RestController
// 对当前Controller下所有接口开启跨域
@CrossOrigin(origins = "http://localhost:4200", 
             allowedHeaders = "*", 
             methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE, RequestMethod.OPTIONS})
public class YourApiController {
    // 接口方法
}

注意事项

  • 生产环境不要使用*作为allowedOrigins,必须指定具体的前端域名,避免安全风险。
  • 如果业务需要保留CSRF防护,需确保OPTIONS预检请求能绕过CSRF校验,可添加csrf().ignoringAntMatchers("/**")(按需调整路径)。
  • 配置完成后,重启Spring Boot服务,再用本地UI测试跨域请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:35:30