当前位置: 首页 > web >正文

[Java实战]Spring Boot 解决跨域问题(十四)

[Java实战]Spring Boot 解决跨域问题(十四)

一、CORS 问题背景
  1. 什么是跨域问题?
    当浏览器通过 JavaScript 发起跨域请求(不同协议、域名、端口)时,会触发同源策略限制,导致请求被拦截。
    示例场景:前端运行在 http://localhost:3000,后端 API 部署在 http://localhost:8080

  2. CORS 机制的作用

    • CORS(Cross-Origin Resource Sharing)是一种基于 HTTP 头的安全机制。
    • 允许服务端声明哪些外部域可以访问资源,解决合法跨域请求的限制。
二、Spring Boot 的 4 种解决方案
1. 使用 @CrossOrigin 注解(Controller 级别)

适用场景:仅需为单个接口或控制器开启跨域支持。
实现方式

@RestController
@RequestMapping("/api")
public class UserController {@CrossOrigin(origins = "http://localhost:3000")@GetMapping("/users")public List<User> getUsers() {return userService.findAll();}
}

配置参数

  • origins:允许的源(支持通配符 *,但不推荐生产环境使用)
  • methods:允许的 HTTP 方法(如 GET, POST
  • allowedHeaders:允许的请求头(如 Content-Type, Authorization
  • maxAge:预检请求缓存时间(单位:秒)
2. 全局 CORS 配置(推荐)

适用场景:为整个应用统一配置跨域规则。
实现方式

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("http://localhost:3000").allowedMethods("GET", "POST", "PUT", "DELETE").allowedHeaders("*").allowCredentials(true).maxAge(3600);}
}

关键配置说明

  • addMapping("/**"):对所有接口生效
  • allowCredentials(true):允许携带 Cookie(需与 allowedOrigins 明确指定域名配合)
3. 结合 Spring Security 的 CORS 配置

适用场景:应用启用了 Spring Security 鉴权,需确保 CORS 配置不被安全过滤器拦截。
实现方式

@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.cors(cors -> cors.configurationSource(corsConfigurationSource())).csrf().disable().authorizeRequests(auth -> auth.anyRequest().authenticated());return http.build();}@BeanCorsConfigurationSource corsConfigurationSource() {CorsConfiguration config = new CorsConfiguration();config.setAllowedOrigins(Arrays.asList("http://localhost:3000"));config.setAllowedMethods(Arrays.asList("GET", "POST"));UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);return source;}
}

注意事项

  • 必须通过 cors.configurationSource() 显式配置,而非仅依赖 WebMvcConfigurer
  • 确保 Spring Security 的过滤器链顺序正确(CORS 处理需在认证之前)。
4. 网关层统一处理(Nginx/Spring Cloud Gateway)

适用场景:微服务架构中,在网关层统一管理跨域策略。
示例(Nginx 配置)

server {listen 80;server_name api.example.com;location / {# CORS 配置add_header 'Access-Control-Allow-Origin' 'http://localhost:3000';add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,Content-Type,Authorization';add_header 'Access-Control-Allow-Credentials' 'true';if ($request_method = 'OPTIONS') {add_header 'Access-Control-Max-Age' 1728000;add_header 'Content-Type' 'text/plain; charset=utf-8';add_header 'Content-Length' 0;return 204;}proxy_pass http://backend-service;}
}
三、最佳实践与调试技巧
  1. 避免使用通配符 *

    • 生产环境中明确指定 allowedOrigins,如 https://your-frontend-domain.com
    • 通配符会导致 allowCredentials(true) 失效,且存在安全风险。
  2. 处理预检请求(OPTIONS)

    • 浏览器对复杂请求(如带自定义头的 POST)会先发送 OPTIONS 请求。
    • 确保后端正确处理 OPTIONS 方法(可通过全局配置或网关层实现)。
  3. 调试工具推荐

    • 浏览器开发者工具:查看 Console 和 Network 标签中的 CORS 错误信息。
    • Postman:验证接口是否正常工作(绕过浏览器限制)。
    • curl 命令:模拟跨域请求:
      curl -H "Origin: http://localhost:3000" -H "Access-Control-Request-Method: GET" -X OPTIONS http://localhost:8080/api/users
      
四、常见问题排查
  1. 配置未生效的可能原因

    • 未正确引入 WebMvcConfigurer 或 Spring Security 配置冲突。
    • 全局配置与 @CrossOrigin 注解混用时优先级问题(注解会覆盖全局配置)。
    • 缓存问题:浏览器可能缓存了旧的 CORS 响应头,需强制刷新(Ctrl + F5)。
  2. Spring Security 导致 CORS 失效

    • 检查安全配置中是否遗漏 .cors() 调用。
    • 确保 CorsConfigurationSource Bean 被正确注册。
  3. 携带 Cookie 时的特殊要求

    • 前端请求需设置 withCredentials: true(Axios 示例):
      axios.get('http://localhost:8080/api/data', { withCredentials: true });
      
    • 后端需配置 allowCredentials(true)allowedOrigins 不能为 *
五、进阶:CORS 与 CSRF 的协同配置

若同时启用 CSRF 保护(如表单提交场景):

@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.cors().configurationSource(corsConfigurationSource()).and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and().authorizeRequests().anyRequest().authenticated();return http.build();}
}

关键点

  • 使用 CookieCsrfTokenRepository 将 CSRF Token 存储在 Cookie 中。
  • 前端需从 Cookie 读取 XSRF-TOKEN 并添加到请求头。
六、总结

通过合理选择注解配置、全局策略或网关层处理,Spring Boot 可以灵活解决各种跨域场景。关键点在于:

  1. 明确需求:区分开发环境与生产环境的配置严格性。
  2. 安全优先:避免过度开放权限,严格限制 allowedOrigins
  3. 全链路验证:结合浏览器工具和后端日志进行调试。

附录:官方文档参考

  • Spring CORS Documentation
  • MDN CORS Guide

希望本教程对您有帮助,请点赞❤️收藏⭐关注支持!欢迎在评论区留言交流技术细节!

http://www.xdnf.cn/news/5409.html

相关文章:

  • 深入探索 RKNN 模型转换之旅
  • llama.cpp初识
  • iVX 平台技术解析:图形化与组件化的融合创新
  • Qt模块化架构设计教程 -- 轻松上手插件开发
  • Vivado中可新建的工程类型解析
  • 招行数字金融挑战赛数据赛道赛题一
  • Java并发编程常见问题与陷阱解析
  • 基础框架搭建流程指南
  • 互联网大厂Java面试实战:从Spring Boot到微服务的技术问答与解析
  • JavaWeb, Spring, Spring Boot
  • LabVIEW车牌自动识别系统
  • E+H流量计通过Profibus DP主站转Modbus TCP网关与上位机轻松通讯
  • Qwen-2.5 omni
  • 浏览器的B/S架构和C/S架构
  • C# Newtonsoft.Json 使用指南
  • STM32学习记录——点灯
  • Qt坐标系 + 信号和槽 + connect函数(8)
  • 从InfluxDB到StarRocks:Grab实现Spark监控平台10倍性能提升
  • 技术书籍推荐(002)
  • MySQL数据库下篇
  • 缓存(4):常见缓存 概念、问题、现象 及 预防问题
  • [项目总结] 抽奖系统项目技术应用总结
  • 小土堆pytorch--torchvision中的数据集的使用dataloader的使用
  • 设计模式之工厂模式(二):实际案例
  • 支持selenium的chrome driver更新到136.0.7103.92
  • 飞蛾扑火算法matlab实现
  • 【仿真】【具身智能仿真】Isaac Simlab云端部署(入门学习性价比最高的方式)
  • 深入解析多选字段的存储与查询:从位运算到数据库设计的最佳实践
  • 仿真生成激光干涉包裹相位数据-用于深度学习训练!
  • Java SE(11)——内部类