网站首页 > 技术文章 正文
引言
"接口调不通?前端同事又双叒叕在吼跨域了!"
"明明Postman能通,浏览器却报OPTIONS 403?"
"生产环境跨域配置突然失效,凌晨3点被夺命连环Call?"
每个后端开发者都经历过被CORS(跨域资源共享)支配的恐惧。本文将手把手教你3种Spring Boot跨域解决方案,从注解到源码配置,从单接口到全局管控,附带防踩坑指南和线上应急预案,从此告别跨域噩梦!
一、跨域问题本质:30秒搞懂CORS核心机制
- 浏览器安全策略:同源策略(Same-Origin Policy)限制不同源的前后端交互
- CORS破局关键:服务端通过HTTP响应头声明允许的跨域规则
- 核心响应头:
http
Access-Control-Allow-Origin: * // 允许的域名(*为通配符)
Access-Control-Allow-Methods: GET,POST // 允许的HTTP方法
Access-Control-Allow-Headers: Content-Type // 允许的请求头
Access-Control-Max-Age: 3600 // 预检请求缓存时间(秒)
二、Spring Boot解决跨域的3种实战方案
方案1:@CrossOrigin注解(精准打击)
适用场景:仅需开放特定接口的跨域访问
java
@RestController
public class UserController {
// 单个方法配置
@CrossOrigin(origins = "https://your-frontend.com",
methods = {RequestMethod.GET, RequestMethod.POST},
allowedHeaders = "Content-Type")
@GetMapping("/api/user")
public User getUser() {
return new User("码农", 28);
}
// 类级别配置(作用于所有接口)
@CrossOrigin(origins = "*")
@RestController
public class OpenApiController {
// ...
}
}
坑点预警:
- 若同时存在全局配置,注解配置会被覆盖!
- 不支持通配符子域名(如 *.domain.com)
方案2:全局配置(一劳永逸)
推荐指数:★★★★★
通过实现WebMvcConfigurer统一管理:
java
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 所有接口
.allowedOrigins("https://prod.com", "http://localhost:8080")
.allowedMethods("*") // 允许所有方法
.allowedHeaders("*") // 允许所有头
.allowCredentials(true) // 允许携带Cookie
.maxAge(1800); // 预检请求缓存时间
}
}
避坑指南:
- allowCredentials(true)时,allowedOrigins不能为*,必须明确指定域名!
- 若使用Spring Security,需额外配置cors()+csrf().disable()(见方案3)
方案3:过滤器(终极自由)
适用场景:需要动态控制跨域规则(如多租户系统)
java
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("https://*.company.com"); // 支持通配符子域名
config.addAllowedMethod("*");
config.addAllowedHeader("*");
config.setMaxAge(3600L);
source.registerCorsConfiguration("/**", config);
return new FilterRegistrationBean<>(new CorsFilter(source));
}
优势:
- 优先级最高,可覆盖其他配置
- 支持复杂逻辑(如从数据库读取允许的域名)
三、深度避坑:那些官方文档不会告诉你的秘密
1. 预检请求(Preflight)的阴谋
- 现象:前端POST请求变成OPTIONS请求
- 本质:浏览器对非简单请求自动发起预检请求
- 解决方案:
- 确保服务器正确处理OPTIONS方法(Spring Boot默认支持)
- 设置合理的maxAge减少预检次数
2. Spring Security的偷袭
症状:明明配置了跨域,却依然返回403
修复方案:
java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors() // 启用CORS支持
.and()
.csrf().disable() // 禁用CSRF(根据业务需要)
.authorizeRequests()
.anyRequest().permitAll();
}
// 关键!提供CorsConfigurationSource
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.applyPermitDefaultValues();
configuration.addAllowedMethod(HttpMethod.PUT); // 按需添加
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
3. 生产环境突发跨域故障应急方案
- 临时允许所有域名(慎用!):
- java
allowedOrigins("*")
- Nginx层统一加响应头:
- nginx
location / {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,Content-Type';
}
- 接口代理:通过后端调用第三方接口,规避浏览器限制
四、最佳实践总结
方案 | 适用场景 | 优点 | 缺点 |
@CrossOrigin | 快速验证、少量接口 | 简单易用 | 配置分散,维护成本高 |
全局配置 | 标准项目 | 统一管理,优先级适中 | 无法动态调整 |
过滤器 | 需要动态规则/微服务网关 | 灵活性强,优先级最高 | 实现稍复杂 |
结语
跨域不是技术难题,而是前后端协作的试金石。掌握这3种方案后,下次再遇到跨域问题,你可以淡定地说:“给我1分钟,马上搞定!”
转发收藏本文,让你团队的前端小伙伴不再抓狂!
讨论话题:你在解决跨域问题时踩过哪些坑? 评论区分享经验,点赞最高的送《Spring Boot实战派》电子书!
附录:常用检测工具
- Chrome开发者工具 → Network标签查看请求头/响应头
- Postman → 关闭CORS限制验证接口本身
- 在线CORS检测工具:https://test-cors.org/
关于作者
资深全栈开发者,曾因CORS问题被前端追杀三条街。专注分享实战开发技巧,关注我,解锁更多《Spring Boot避坑指南》!
猜你喜欢
- 2025-06-03 Spring Boot跨域难题终结者:3种方案,从此告别CORS噩梦!
- 2025-06-03 京东大佬问我,SpringBoot为什么会出现跨域问题?如何解决?
- 2025-06-03 在 Spring Boot3 中轻松解决接口跨域访问问题
- 2025-06-03 最常见五种跨域解决方案(常见跨域及其解决方案)
- 2025-06-03 Java Web开发中优雅应对跨域问题(java跨域问题解决办法)
- 2025-06-03 Spring Boot解决跨域最全指南:从入门到放弃?不,到根治!
- 2025-06-03 Spring Cloud 轻松解决跨域,别再乱用了
- 2024-09-27 ASP.NET实战007:MVC解决跨域请求问题详解
- 2024-09-27 一文带你彻底搞懂跨域那些事(不只会用)
- 2024-09-27 程序员如何处理跨域问题,记住这一点就够了
你 发表评论:
欢迎- 489℃几个Oracle空值处理函数 oracle处理null值的函数
- 484℃Oracle分析函数之Lag和Lead()使用
- 483℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 469℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 463℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 458℃【数据统计分析】详解Oracle分组函数之CUBE
- 440℃Oracle有哪些常见的函数? oracle中常用的函数
- 436℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 最近发表
-
- Spring Boot跨域难题终结者:3种方案,从此告别CORS噩梦!
- 京东大佬问我,SpringBoot为什么会出现跨域问题?如何解决?
- 在 Spring Boot3 中轻松解决接口跨域访问问题
- 最常见五种跨域解决方案(常见跨域及其解决方案)
- Java Web开发中优雅应对跨域问题(java跨域问题解决办法)
- Spring Boot解决跨域最全指南:从入门到放弃?不,到根治!
- Spring Boot跨域问题终极解决方案:3种方案彻底告别CORS错误
- Spring Cloud 轻松解决跨域,别再乱用了
- Github 太狠了,居然把 "master" 干掉了
- IntelliJ IDEA 调试 Java 8,实在太香了
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端富文本编辑器 (47)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)