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

配置Spring Boot CORS后仍报错,Angular跨域请求受阻如何解决?

解决Spring Boot + Angular的CORS跨域问题

报错信息

跨源请求被阻止:同源策略不允许读取位于http://localhost:8082/api/countries的远程资源。
Access to XMLHttpRequest at 'http://localhost:8082/api/countries' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
checkout.component.ts:153     GET http://localhost:8082/api/countries net::ERR_FAILED

问题背景

后端基于Spring Boot,已配置:

  • 优先级最高的CorsFilter Bean,允许源为http://localhost:4200
  • 引入spring-boot-starter-data-rest依赖
  • CountryRepository添加@CrossOrigin注解
  • RestAppConfig配置CorsRegistry

前端使用Angular 15:

  • Checkout组件的ngOnInit中调用FormService.getCountries请求接口
  • 配置AuthInterceptor为请求添加Authorization头

以下是具体排查和解决步骤:

1. 修正CorsFilter配置,覆盖预请求

确保CorsFilter完整覆盖预请求(OPTIONS),并包含必要的响应头:

@Bean
public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    // Spring Boot 2.4+推荐使用集合形式或origin pattern
    config.setAllowedOrigins(Collections.singletonList("http://localhost:4200"));
    // 允许所有请求方法,包括OPTIONS
    config.addAllowedMethod("*");
    // 允许Authorization等自定义请求头
    config.addAllowedHeader("*");
    // 暴露前端需要读取的响应头
    config.addExposedHeader("Authorization");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

2. 移除冲突的跨域配置

多个跨域配置会互相干扰,建议只保留一种配置方式:

  • 暂时注释CountryRepository上的@CrossOrigin注解
  • 停用RestAppConfig中的CorsRegistry配置
  • 优先保证CorsFilter的唯一性,因为它的优先级高于Data REST的默认配置

3. 放行OPTIONS预请求(若有Spring Security)

带Authorization头的请求会触发OPTIONS预请求,必须确保该请求无需认证:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().and()
        .authorizeRequests()
        // 放行所有OPTIONS请求
        .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
        .anyRequest().authenticated();
}

4. 修正Angular拦截器逻辑

拦截器需跳过OPTIONS请求,避免手动添加头导致预请求失败:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // 预请求由浏览器自动处理,无需添加Authorization头
    if (request.method === 'OPTIONS') {
        return next.handle(request);
    }
    const authToken = localStorage.getItem('authToken');
    if (authToken) {
        request = request.clone({
            setHeaders: {
                Authorization: `Bearer ${authToken}`
            }
        });
    }
    return next.handle(request);
}

5. 清除浏览器缓存

浏览器可能缓存旧的CORS错误响应,使用无痕模式或清除缓存后重新测试。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:30:24