Spring服务POST请求时Angular前端遇OPTIONS 403错误求助
解决Spring后端+Angular前端POST请求OPTIONS 403问题
这种情况我之前碰到过好几次,核心问题就是Spring后端没有正确处理浏览器自动发送的OPTIONS预检请求。Postman不会触发预检流程,所以能正常POST;但浏览器会先发送OPTIONS请求确认服务器是否允许跨域操作,你的后端没放行这个请求,就返回了403。下面给你几个靠谱的解决办法:
1. 检查Controller级别的CORS注解配置
如果你的Controller用了@CrossOrigin注解,要确保它覆盖了OPTIONS方法,不然预检请求会被拒绝:
// 在Controller类或单个方法上添加 @CrossOrigin( origins = "http://localhost:4200", // 你的Angular本地地址 allowedMethods = {"GET", "POST", "OPTIONS"}, // 显式包含OPTIONS allowedHeaders = "*", allowCredentials = true )
嫌麻烦的话也可以直接用allowedMethods = "*"来放行所有HTTP方法。
2. 配置全局CORS(更推荐多Controller场景)
写一个全局配置类,统一处理所有接口的跨域请求,避免每个Controller重复注解:
@Configuration public class GlobalCorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:4200") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); // 缓存预检请求结果,减少重复请求 } }
3. 若使用Spring Security,必须额外放行OPTIONS请求
Spring Security的过滤器链优先级高于CORS处理,所以要单独配置放行OPTIONS请求,否则会被权限拦截:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .cors().and() // 启用全局CORS配置 .authorizeRequests() .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 显式放行所有OPTIONS请求 .anyRequest().authenticated(); // 其他Security配置(比如csrf、登录逻辑等) } // 如果用了全局CORS,这里可以注入配置源 @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; } }
4. 排查自定义拦截器是否拦截了OPTIONS请求
如果你自己写了请求拦截器,检查是否误拦截了OPTIONS请求。可以在拦截器的preHandle方法里添加判断:
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 直接放行OPTIONS预检请求 if (HttpMethod.OPTIONS.name().equals(request.getMethod())) { return true; } // 你的其他拦截逻辑... return true; }
另外提一句:Chrome的CORS插件经常因为浏览器缓存、插件优先级问题不生效,别依赖插件,还是得从后端配置入手。按照上面的步骤调整后,重启Spring服务,再试Angular的POST请求应该就能解决了。
内容的提问来源于stack exchange,提问作者Nickknack
相关产品推荐
相关产品推荐

