React对接SpringBoot:CORS拦截Post/Put/Delete但Get请求正常
解决CORS预请求拦截问题(POST/PUT/DELETE请求失效)
问题场景
控制台报错:
Access to XMLHttpRequest at 'http://localhost:9191/api/v1/employee' from origin 'http://localhost:3000' 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.
后端已配置全局CORS,但仅GET请求可正常工作,POST/PUT/DELETE请求均被CORS拦截,接口示例:
@PostMapping(value = "/employee") @ResponseBody public EmployeeDTO createEmployee(EmployeeDTO employee){ return employeeService.createEmployee(employee); } @GetMapping("/employee") public List<EmployeeDTO> getEmployees(){ return employeeService.getAllEmployees(); }
问题原因
GET属于简单请求,浏览器不会触发OPTIONS预请求;而POST/PUT/DELETE若携带application/json类型数据,属于非简单请求,浏览器会先发送OPTIONS预请求验证跨域权限。- 全局CORS配置可能未正确处理OPTIONS请求,或未声明允许
POST/PUT/DELETE等方法;也可能被Spring Security这类安全框架拦截了OPTIONS预请求。 - 另外,你的
POST接口参数未添加@RequestBody注解,若前端以JSON格式传参,后端无法正确接收参数,这可能间接引发请求异常,但当前核心问题是CORS预请求未通过。
解决方案
1. 修正全局CORS配置,覆盖OPTIONS请求及所需HTTP方法
以Spring Boot为例,全局CORS配置需明确包含OPTIONS请求和所有需要的HTTP方法:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:3000") // 指定允许的前端域名 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 包含OPTIONS预请求 .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); // 缓存预请求结果,减少重复OPTIONS请求 } }
2. 若使用Spring Security,需放行OPTIONS请求并优先处理CORS
如果项目集成了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(); } // 也可在此直接配置CORS,替代WebMvcConfigurer的配置 @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); configuration.setAllowedHeaders(Arrays.asList("*")); configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
3. 修正POST接口参数注解
如果前端以JSON格式传递参数,需给EmployeeDTO参数添加@RequestBody注解,确保后端正确接收:
@PostMapping(value = "/employee") @ResponseBody public EmployeeDTO createEmployee(@RequestBody EmployeeDTO employee){ return employeeService.createEmployee(employee); }
内容的提问来源于stack exchange,提问作者Johnny Boy
相关产品推荐
相关产品推荐

