一、前言:为什么前后端联调需要跨域配置
在前后端分离的项目中,前端项目在 http://localhost:8081,后端在 http://localhost:8080。浏览器为了安全,会遵守同源策略(协议、域名、端口必须完全一致)。只要端口号不同,就算“跨域”。

浏览器会先发一个 OPTIONS 预检请求“探路”,如果后端没配置跨域“通行证”,请求就会被拦截,前端报出经典的 CORS error(跨域资源共享错误)。
解决核心:跨域配置就是在后端告诉浏览器——“这个前端来源(Origin)允许放行(⌐■_■)”
二、Spring Boot 配置跨域的三种方式
方式一:全局配置类(最推荐)
新建一个配置类,实现 WebMvcConfigurer 接口。优点是统一管理所有接口,一劳永逸。
方式二:局部注解(快速测试用)
在 Controller 类或具体方法上加 @CrossOrigin 注解,只针对这一个控制器生效。
方式三:过滤器(Filter)配置
通过 @Bean 定义 CorsFilter,适用于 Spring Security 等复杂权限场景,配置更底层,但代码略繁琐(零基础前期不建议优先使用)。
三、代码实例逐行拆解
现在我们用方式一:全局配置类来做个示范,新建 config/CorsConfig 配置类
package org.example.starway_wards_backend.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration // 1. 标记配置类,Spring启动时会自动加载
public class CorsConfig implements WebMvcConfigurer { // 2. 重点接口实现,配置Spring MVC行为
@Override
public void addCorsMappings(CorsRegistry registry) { // 3. 重写跨域映射方法
registry.addMapping("/**") // 拦截所有接口路径
.allowedOriginPatterns("*") // 允许所有前端来源(开发环境时)
.allowedMethods("*") // 允许所有HTTP请求方法(GET/POST等)
.allowedHeaders("*") // 允许前端携带的所有请求头
.allowCredentials(true); // 允许携带Cookie/Token凭证
}
}
四、语法讲解
1. 核心注解速记
| @CrossOrigin | 声明这是一个Spring配置类 |
| WebMvcConfigurer | 接管Spring MVC的配置 |
| @Override | 重写父类方法(固定写法) |
2.跨域映射方法 addCorsMapping 中的常用链式方法
| addMaping | "/**" 或 "/api/**" | 放行哪些接口:/** 代表全部,/api/** 只管业务接口,必加 |
| allowedOringinPatterns | "*" 或 "https://域名.com" |
什么网站可以进:允许哪些前端域名访问。 注意:这是新写法,支持带凭证的通配符! |
| allowedMethods | "*" 或 {"GET","POST"} | 允许用什么方式:允许哪些HTTP方法(GET, POST, PUT, DELETE)。 |
| allowedHeaders | "*" 或 "Authorization" | 允许带什么装备:允许前端请求头携带什么字段(如Token)。 |
| allowCredentials | true 或 false | 是否允许带干粮:是否允许携带Cookie。设为true时,前端withCredentials也要开。 |
| exposedHeaders | "X-Total-Count" | 让前端能看到什么:后端返回了自定义头,默认前端JS读不到,用这个暴露出来。 |
| maxAge | 3600(秒) | 缓存多久:浏览器缓存预检(OPTIONS)结果的时间,避免每次都发两次请求,性能优化必加。 |
3. 新旧语法对比(面试高频坑)
📌 allowedOrigins("*")
表示后端允许任何域名的请求!是springboot2.4.0版本前的写法,有着巨大的安全风险,往后版本不能与 allowCredentials(true) 一起使用,否则启动会失败!
/* 错误写法(经典报错组合):当 allowCredentials = true 时,allowedOrigins 不能用 "*"
.allowedOrigins("*")
.allowCredentials(true)
运行直接抛异常: "When allowCredentials is true, allowedOrigins cannot contain the special value *" */
// 正确写法:必须改用 allowedOriginPatterns
.allowedOriginPatterns("*")
.allowCredentials(true)
五、生产环境改造
注意一点,开发环境用 * 没问题,生产打包时最好替换成制定路径,防止恶意链接请求
// 生产环境改动
registry.addMapping("/api/**") // 只拦截业务接口,少拦截静态资源
.allowedOriginPatterns("https://前端部署域名.com") // 只有自家域名能调
.allowedMethods("GET", "POST", "PUT", "DELETE") // 按需开放,* 少用
.allowedHeaders("Authorization", "Content-Type") // 只开放必要的头
.allowCredentials(true)
.maxAge(3600); // 缓存预检1小时,减少OPTIONS请求
六、@CrossOrigin 局部注解速记
当不想写全局配置时,直接按方法二在控制器上加注解:
@RestController
@CrossOrigin(origins = "*", maxAge = 3600) // 允许所有来源,缓存1小时
public class TestController {
// …
}
区别速记:
-
全局配置(WebMvcConfigurer):管所有Controller,优先级最高,适合统一管理。
-
局部注解(@CrossOrigin):只管当前类或方法,适合临时测试。
七、总结
开发时:直接用你提供的 CorsConfig 模板,记住用 allowedOriginPatterns 替代 allowedOrigins。
特殊注意:记住 allowCredentials(true) 和通配符 * 不能共存(除非用 Patterns)。
上线时:把 * 替换成具体域名,并把 allowedMethods 和 allowedHeaders 收窄,同时加上 maxAge 优化性能。




