springboot 跨域(手把手讲解)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在 Web 开发中,"Spring Boot 跨域" 是一个高频出现且容易引发困惑的问题。随着前后端分离架构的普及,前端页面与后端 API 通常运行在不同的端口或域名下,这种场景下浏览器会触发跨域限制,导致请求被拦截。本文将从跨域问题的根源讲起,逐步解析 Spring Boot 中的解决方案,并通过实际案例和代码示例,帮助开发者快速掌握这一核心知识点。


一、理解跨域问题:从快递公司到浏览器安全机制

1.1 跨域的定义与成因

跨域(Cross-Origin)问题源于浏览器的同源策略(Same-Origin Policy)。简单来说,当请求的 URL 协议、域名或端口与当前页面的来源不一致时,浏览器会认为这是跨域请求,并默认阻止该请求以保护用户隐私。

形象比喻
可以把浏览器比作一个严格的快递公司。当你从上海寄包裹到北京(不同端口),快递员会正常派送;但如果包裹上写着收件地址是另一个快递公司的仓库(不同域名),快递员会直接拒绝接收,除非收件方明确授权。

1.2 跨域的典型场景

以下情况会触发跨域限制:

  • 前端页面运行在 http://localhost:8080,请求后端 API http://localhost:8081/api
  • 移动端 H5 页面访问 PC 端 API
  • 使用不同子域名(如 a.example.com 请求 b.example.com

1.3 浏览器如何处理跨域请求

浏览器通过以下流程处理跨域请求:

  1. 检测请求是否跨域
  2. 若跨域,则添加 Origin 头并发送预检请求(OPTIONS)
  3. 服务器响应时,需携带 Access-Control-Allow-Origin 等 CORS 头字段
  4. 浏览器验证响应头,决定是否允许访问响应内容

二、Spring Boot 跨域解决方案:从简单配置到进阶技巧

2.1 核心概念:CORS 与全局配置

CORS(跨域资源共享)是浏览器与服务器协商跨域权限的标准机制。Spring Boot 提供了 @CrossOrigin 注解和全局配置两种方式来实现 CORS。

2.1.1 单个接口配置(@CrossOrigin)

通过在 Controller 方法或类上添加 @CrossOrigin 注解,可为指定接口开启跨域权限。

@RestController  
@RequestMapping("/api")  
public class UserController {  
    @CrossOrigin(origins = "http://localhost:3000") // 允许的前端地址  
    @GetMapping("/users")  
    public List<User> getUsers() {  
        // 接口逻辑  
    }  
}  

关键参数说明

  • origins:允许访问的源列表(支持通配符 *,但生产环境应显式指定)
  • methods:允许的 HTTP 方法(默认为请求方法)
  • allowedHeaders:允许的请求头
  • exposedHeaders:允许暴露给前端的响应头

2.1.2 全局配置(推荐)

通过继承 WebMvcConfigurer 接口,可为整个应用配置默认的 CORS 策略,避免重复代码。

@Configuration  
public class CorsConfig implements WebMvcConfigurer {  
    @Override  
    public void addCorsMappings(CorsRegistry registry) {  
        registry.addMapping("/**") // 应用到所有路径  
                .allowedOrigins("http://localhost:3000")  
                .allowedMethods("GET", "POST", "PUT", "DELETE")  
                .allowCredentials(true) // 允许携带 Cookie  
                .maxAge(3600); // 预检请求缓存时间(秒)  
    }  
}  

注意:当配置 allowedOrigins* 时,allowCredentials 必须设为 false,否则浏览器会拒绝请求。


三、实战案例:从问题复现到解决方案

3.1 问题复现:一个简单的跨域错误

假设前端页面运行在 http://localhost:3000,请求后端接口 http://localhost:8080/api/data,此时浏览器控制台会报错:

Access to XMLHttpRequest at 'http://localhost:8080/api/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

3.2 解决方案:配置全局 CORS

按照以下步骤修复问题:

  1. 在 Spring Boot 工程中创建 CorsConfig 类(如 2.1.2 节代码)
  2. 确保 @Configuration 注解生效
  3. 测试请求,观察响应头中是否包含 Access-Control-Allow-Origin

3.3 验证响应头

通过浏览器开发者工具的 Network 标签,查看响应头应包含以下字段:

Access-Control-Allow-Origin: http://localhost:3000  
Access-Control-Allow-Methods: GET, POST, PUT, DELETE  
Access-Control-Allow-Credentials: true  

四、进阶技巧:动态配置与安全性优化

4.1 动态允许来源(基于请求参数)

在某些场景下,需要根据请求来源动态决定是否允许跨域。可通过自定义 CorsProcessor 实现:

@Configuration  
public class DynamicCorsConfig {  
    @Bean  
    public CorsFilter corsFilter() {  
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  
        CorsConfiguration config = new CorsConfiguration();  
        config.setAllowedOrigins(Arrays.asList("http://client1.com", "http://client2.com"));  
        config.addAllowedMethod("*");  
        source.registerCorsConfiguration("/**", config);  
        return new CorsFilter(source);  
    }  
}  

4.2 安全性优化建议

  • 避免使用通配符 *:生产环境应明确列出可信域名
  • 限制 HTTP 方法:仅允许必要操作(如 REST API 通常不需要 DELETE
  • 禁用敏感头暴露:确保 exposedHeaders 不包含 Cookie 等敏感信息
  • 结合安全框架:与 Spring Security 结合时,需配置 CORS 过滤器顺序

五、常见问题与排查方法

5.1 常见错误场景及解决方案

错误现象可能原因解决方案
跨域请求被拦截前端地址未在 allowedOrigins更新配置文件并重启服务
无法携带 CookieallowCredentials 未设置为 true在 CORS 配置中显式开启
预检请求失败请求头包含非允许字段(如 Content-Type: application/jsonallowedHeaders 中添加对应字段

5.2 调试工具推荐

  • Postman:可绕过浏览器限制测试接口
  • Chrome 开发者工具:通过 Network 标签查看详细响应头
  • Spring Boot 日志:启用 DEBUG 级别日志查看 CORS 处理过程

结论

Spring Boot 跨域问题的本质是浏览器安全策略与开发需求的冲突,而通过合理配置 CORS 机制可以高效解决这一问题。本文从基础概念到实战案例,再到进阶优化,逐步展示了如何在 Spring Boot 中实现跨域访问。开发者应根据实际场景选择配置方式,并始终关注安全性与灵活性的平衡。掌握这一知识点后,您将能够更从容地构建前后端分离的应用系统,为用户提供无缝的交互体验。

提示:当遇到复杂跨域场景时,可结合 @CrossOrigin 注解的细粒度控制与全局配置的默认策略,实现精准权限管理。

最新发布