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

Spring配置@CrossOrigin后,Angular带JWT请求仍遭CORS拦截

问题原因及解决方案

带Authorization头的跨域请求会触发浏览器的预检OPTIONS请求,你当前控制器上的@CrossOrigin注解没覆盖到这个预检请求的处理,导致响应里缺失CORS相关头,所以浏览器报错。Postman不属于浏览器环境,不会发送预检请求,因此能正常调用。

以下是几种解决办法:

1. 结合Spring Security配置CORS(如果用了Security)

如果你的项目集成了Spring Security,Security过滤器链会优先于控制器的注解处理请求,所以需要在Security配置里专门放行OPTIONS请求并配置CORS:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // 启用CORS配置
            .cors(cors -> cors.configurationSource(corsConfigurationSource()))
            .csrf(csrf -> csrf.disable()) // 若不需要CSRF保护可关闭
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/auth/**").permitAll() // 放行认证接口
                .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 放行所有OPTIONS预检请求
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())); // 适配JWT认证
        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Collections.singletonList("*"));
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        config.setAllowedHeaders(Collections.singletonList("*"));
        
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

2. 全局配置CORS(替代控制器注解)

全局配置会覆盖所有请求路径,包括预检OPTIONS请求,比控制器级别的注解更可靠:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*");
    }
}

注意:如果需要允许携带凭证(比如Cookie),allowedOrigins不能设为*,要指定具体的前端地址(如http://localhost:4200),同时开启allowCredentials(true)。

3. 确保控制器处理OPTIONS请求(不推荐)

如果坚持用控制器级别的注解,需要确保控制器的请求映射支持OPTIONS方法,比如:

@RestController
@CrossOrigin(origins = "*", allowedHeaders = "*", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.OPTIONS})
@RequestMapping("/sensors")
public class SensorController {
    // 接口实现
}

这种方式仅作用于当前控制器,灵活性较差,一般不推荐使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:05:22