目录
- 方法 1:使用 @CrossOrigin 注php解(最简单)
- 优点:
- 缺点:
- 方法 2:全局配置 CORS(推荐!)
- 方式 A:实现 WebMvcConfigurer 接口(Spring Boot 2.x+)
- 方式 B:使用 @Bean 注册 CorsConfigurationSource
- 优点:
- 方法 3:通过 Filter 自定义 CORS(底层控制)
- 优点:
- 缺点:
- 场景 1:Spring WebFlux(响应式)项目
- 场景 2:Spring Boot Actuator 端点的 CORS 配置
- 方法 4:结合 Spring Security 配置 CORS(安全场景必备)
- 常见错误
- 最佳实践
- 一句话记住:
在 Spring Boot 中解决跨域(CORS,Cross-Origin Resource Sharing)问题有 多种方式,适用于不同场景。下面系统地介绍 5 种主流方法,从简单到灵活,附代码示例和适用场景。
方法 1:使用 @CrossOrigin 注解(最简单)
适用场景: 单个 Controller 或方法需要跨域
@RestController
@CrossOrigin(origins = "http://localhost:3000") // 允许指定来源
public class UserController {
@GetMapping("/user")
public User getUser() {
return new User("John");
}
// 或只对某个方法生效
@CrossOrigin(origins = "*") // 允许所有来源(生产环境慎用!)
@PostMapping("/save")
public String save() {
return "ok";
}
}
优点:
- 简单、直观
- 可细粒度控制(类级别 or 方法级别)
缺点:
- 无法全局统一管理
- 不适合大型项目
方法 2:全局配置 CORS(推荐!)
适用场景: 整个应用统一处理跨域(最常用)
方式 A:实现 WebMvcConfigurer 接口(Spring Boot 2.x+)
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void aTeLeVvrCddCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 拦截所有路径
.allowedOrigins("*")
// .allowedOrigins("http://localhost:3000", "https://your-app.com")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
// .allowCredentials(true) // 是否允许携带 cookie,⚠️ 注意:这里不能同时设为 true!
.maxAge(3600); // 预检请求缓存时间(秒)
}
}
方式 B:使用 @Bean 注册 CorsConfigurationSource
@Configuration
public class CorsConfig {
@Bean
public CorsConfigurationSource corsConfigurationSource()www.devze.com {php
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
// config.setAllowedOrigins(Arrays.asList("*")); // 允许所有域
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
config.setAllowedHeaders(Arrays.asList("*"));
config.setAllowCredentials(true);
// config.setAllowCredentials(true); // ⚠️ 不能与 "*" 同时使用!
UrlBasedCorsConfigurationSo编程urce source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}
优点:
- 全局生效,配置集中
- 灵活控制路径、方法、头部等
- 生产环境推荐方式
方法 3:通过 Filter 自定义 CORS(底层控制)
适用场景: 需要完全自定义 CORS 响应头,或与 Spring Security 集成
@Component
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
// response.setHeader("Access-Control-Allow-Origin", "*");
// 注意:没有 Allow-Credentials!
response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
// 如果是预检请求(OPTIONS),直接返回
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
}
注意:如果使用 Spring Security,需确保此 Filter 在 Security Filter 之前执行。
优点:
- 完全控制响应头
- 可处理复杂逻辑(如动态 origin)
缺点:
- 代码较繁琐
- 容易出错(如漏掉 OPTIONS 处理)✅ 方法 4:在 application.yml / application.properties 中配置(仅限 Spring Boot 2.4+)
注意:Spring Boot 本身不支持通过配置文件直接开启 CORS! 但如果你使用 Spring Cloud Gateway 或 某些 starter,可能有扩展支持。
普通 Spring Boot Web 项目不能这样配置!
所以:不要尝试在 application.yml 里写 cors 配置(除非你用的是特定网关组件)。
场景 1:Spring WebFlux(响应式)项目
application.yml
spring:
webflux:
cors:
allowed-origins: "*"
allowed-methods: "GET,POST,PUT,DELETE,OPTIONS"
allowed-headers: "*"
max-age: 3600
场景 2:Spring Boot Actuator 端点的 CORS 配置
即使你用的是 Spring MVC,Actuator 的监控端点也支持通过配置文件开启 CORS:
application.yml
management:
endpoints:
web:
cors:
allowed-origins: "http://localhost:3000"
allowed-methods: "*"
allowed-headers: "*"
| 项目类型 | 是否支持 application.yml 配置 CORS | 推荐方式 |
|---|---|---|
Spring MVC(spring-boot-starter-web) | ❌ 不支持 | 使用 WebMvcConfigurer 或 @CrossOrigin |
Spring WebFlux(spring-boot-starter-webflux) | ✅ 支持 | 用 spring.webflux.cors.* |
| Actuator 端点 | ✅ 支持(仅限监控接口) | 用 management.endpoints.web.cors.* |
方法 4:结合 Spring Security 配置 CORS(安全场景必备)
如果你的项目用了 Spring Security,必须显式启用 CORS,否则 Security 会拦截 OPTIONS 请求!
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors().and() // 关键:启用 CORS 支持
.csrf().disable()
.authorizeHttpRequests(auth -> auth
.anyRequest().permitAll()
);
return http.build();
}
// 同时提供全局 CorsConfigurationSource
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
configuration.setAllowedMethods(Arrays.asList("*"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
为什么需要?
- Spring Security 默认不处理 CORS
- 如果不配置,浏览器预检请求(OPTIONS)会被 Security 拦截 → 跨域失败
常见错误
| 问题 | 说明 |
|---|---|
allowedOrigins("*") + allowCredentials(true) 冲突 | 浏览器不允许:Access-Control-Allow-Origin 为 * 时,不能带 cookie。必须指定具体 origin |
| 忘记处理 OPTIONS 请求 | 预检请求失败,导致跨域报错 |
| CORS 配置被 Security 覆盖 | 必须在 Spring Security 中显式启用 .cors(),否则 OPTIONS 请求会被拦截 |
生产环境使用 allowedOrigins("*") | 存在安全风险,应明确指定可信的前端域名 |
最佳实践
| 场景 | 推荐方案 |
|---|---|
| 快速测试 / 小型项目 | 使用 @CrossOrigin 注解 |
| 标准 Web 项目(未集成 Spring Security) | 实现 WebMvcConfigurer 进行全局 CORS 配置 |
| 项目已集成 Spring Security | 在 Security 配置中调用 .cors(),并提供 CorsConfigurationSource Bean |
| 需要动态 Origin(如多租户、白名单配置) | 自定义 CorsFilter 实现灵活控制 |
一句话记住:
普通项目用 WebMvcConfigurer,带 Security 的项目必须在 Security 中 .cors() 并提供 CorsConfigurationSource。
以上就是SpringBoot解决跨域的五种方式的详细内容,更多关于SpringBoot解决跨域的资料请关注编程客栈(www.devze.com)其它相关文章!
加载中,请稍侯......
精彩评论