React+Axios调用Spring Boot接口出现CORS跨域错误的排查与解决
跨域问题排查与修复(Spring Boot 2.7.5 + React)
问题详情
调用Spring Boot接口http://localhost:8080/api/createData时,React和Postman均触发跨域错误,报错信息:
Access to XMLHttpRequest at 'http://localhost:8080/api/createData' from origin 'http://localhost:3001' 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.
相关代码
React Axios请求代码:
return axios.post("http://localhost:8080/api/createData", { name: 'Michael' });
Spring Boot pom.xml核心依赖:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 其他依赖省略 --> </dependencies>
请求Controller类:
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") public class Tutorial { @PostMapping("/createData") public void createData(@RequestBody Data data) { System.out.println(data.getName()); } }
问题原因
跨域错误源于浏览器同源策略:当请求的源(http://localhost:3001)与服务端(http://localhost:8080)的端口不同时,属于跨域请求。对于带请求体的POST请求,浏览器会先发送OPTIONS预检请求,验证服务端是否允许跨域。当前Spring Boot服务未配置CORS规则,无法返回Access-Control-Allow-Origin等必要响应头,导致请求被拦截。
Postman出现该问题通常是因为请求头中携带了Origin字段,触发了服务端的跨域校验逻辑。
修复方案
方案1:全局CORS配置(推荐)
创建全局CORS配置类,对所有接口生效:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") // 匹配需要跨域的接口路径 .allowedOrigins("http://localhost:3001") // 允许的前端源 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的请求方法 .allowedHeaders("*") // 允许的请求头 .allowCredentials(true); // 是否允许携带Cookie } }
方案2:控制器/方法级别注解
在Controller类或单个方法上添加@CrossOrigin注解,灵活控制跨域规则:
// 对整个Controller生效 @RestController @RequestMapping("/api") @CrossOrigin(origins = "http://localhost:3001", allowedHeaders = "*", methods = {RequestMethod.GET, RequestMethod.POST}) public class Tutorial { @PostMapping("/createData") // 仅对该方法生效 // @CrossOrigin(origins = "http://localhost:3001") public void createData(@RequestBody Data data) { System.out.println(data.getName()); } }
方案3:CORS过滤器
通过注册过滤器实现全局跨域控制,适合需要更复杂逻辑的场景:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Configuration public class CorsFilterConfig { @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("http://localhost:3001"); config.addAllowedMethod("*"); config.addAllowedHeader("*"); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/api/**", config); return new CorsFilter(source); } }
验证
重启Spring Boot服务后,重新用React和Postman发起请求,跨域错误应消失。
内容的提问来源于stack exchange,提问作者kernel
相关产品推荐
相关产品推荐

