Spring Boot 全局跨域(CORS)配置详解:一段 CorsConfig 代码在干什么?
一、为什么需要跨域配置?
浏览器有一条安全策略:页面里的 JavaScript 不能随便访问「另一个网站」的接口。
举个常见场景:
- 前端页面部署在:
https://a.com - 后端接口在:
https://api.b.com
用户在 a.com 打开页面,前端用 fetch / axios 去请求 api.b.com。这时浏览器会先做一件事:向 api.b.com 确认——是否允许来自 a.com 的跨站访问。
这种「先问能不能」的机制,就是 CORS(Cross-Origin Resource Sharing,跨域资源共享)。
后端如果什么都不配,浏览器可能直接拦截请求,前端控制台出现类似 blocked by CORS policy 的报错。
你在 Spring 里写的 CorsConfig,作用就是:配合浏览器完成 CORS 检查,并声明:允许哪些来源、哪些 HTTP 方法、哪些请求头、是否允许带 Cookie 等。
补充: CORS 只约束「浏览器里的网页脚本」。用 Postman、curl、服务端互相调用,不走这套规则,所以会出现「Postman 能通、浏览器报跨域」的现象,这是正常的。
二、示例代码:全局 CORS 配置
/**
* 全局跨域配置
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 覆盖所有请求
//** 表示:本项目里几乎所有路径(所有 Controller 的接口)都应用这套跨域规则。
registry.addMapping("/**")
// 允许发送 Cookie
.allowCredentials(true)
// 放行哪些域名(必须用 patterns,否则 * 会和 allowCredentials 冲突)
.allowedOriginPatterns("*")
// 放行哪些请求方式2
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
//允许前端带哪些请求头
.allowedHeaders("*")
// 暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
.exposedHeaders("*");
}
}
下面按「这段代码在干什么」逐块说明。
三、@Configuration 与 WebMvcConfigurer
@Configuration:声明这是一个 Spring 配置类,会在应用启动时被加载,里面的 Bean / 配置会生效。implements WebMvcConfigurer:实现 Spring MVC 提供的扩展接口,通过重写方法定制 Web 行为,例如:- 跨域(CORS)
- 拦截器
- 静态资源映射
- 消息转换器等
这里重写的是 addCorsMappings,专门用于 跨域规则。
四、registry.addMapping("/**"):对哪些路径生效?
/**:表示项目里 几乎所有 URL 都会应用这套 CORS 规则(通常等价于「所有 Controller 接口」)。
若只想开放部分接口,可以写成更细的路径,例如 /api/**。
五、allowCredentials(true):是否允许携带凭证?
凭证常见包括:
- Cookie(会话、登录态)
- 某些场景下与认证相关的设置
设为 true 表示:当前端使用例如:
fetch(url, { credentials: 'include' })- 或 axios:
withCredentials: true
浏览器可以把 Cookie 等凭证 一并发给后端,且后端在 CORS 策略上 允许 这类请求。
注意: 一旦开启 allowCredentials(true),浏览器对「允许的来源」会更严格。历史上若用 allowedOrigins("*") 搭配凭证,容易和规范冲突。因此 Spring 里常用 allowedOriginPatterns 等方式,在需要凭证时更灵活地配置来源(见下一节)。
六、allowedOriginPatterns("*"):允许哪些「来源」?
**来源(Origin)**可以理解为:用户当前页面所在的站点,例如 https://a.com。
"*"(pattern) 在这里表示:任意来源 的页面都可以跨域访问你的接口(在开发与内网环境很方便)。
和 allowedOrigins("*") 的差异(通俗理解):
allowedOriginPatterns支持模式匹配,且在 需要凭证 时,比简单写死*更容易符合实际使用方式。
生产环境提醒: * 非常宽松,任意网站的页面都可能让用户浏览器去请求你的接口。若同时还允许带 Cookie,被恶意站点滥用的风险会上升。线上常见做法是改为 白名单域名(例如只允许 https://www.xxx.com、https://admin.xxx.com)。
七、allowedMethods(...):允许哪些 HTTP 方法?
这里列出了:GET、POST、PUT、DELETE、OPTIONS。
为什么要包含 OPTIONS?
对「非简单请求」,浏览器往往会先发一个 OPTIONS 预检请求(preflight),询问服务器:接下来我要用某种方法、带某些头,你是否允许?
若后端没有把 OPTIONS 配进允许的方法,预检可能失败,真正的 POST 等请求就不会发出去。
八、allowedHeaders("*"):允许哪些请求头?
* 表示:允许客户端携带任意请求头(在允许的范围内),例如:
Content-Type(如application/json)Authorization- 业务自定义头
若这里配置过窄,而前端多带了某个头,可能导致 预检失败。
九、exposedHeaders("*"):暴露哪些响应头给前端 JS?
默认情况下,浏览器 只允许 JavaScript 读取部分标准响应头。
如果后端设置了自定义响应头(例如分页总数 X-Total-Count、文件下载名等),前端脚本要读取,就需要在 CORS 中 声明暴露(expose) 这些头。
* 在这里表示:尽可能把可暴露的响应头开放给前端(具体以 Spring 版本与实现为准)。
十、两个常见「坑」小结
| 现象 | 说明 |
|---|---|
|
Postman 正常,浏览器跨域 |
CORS 是浏览器策略;Postman 不模拟浏览器的同源限制。 |
|
|
学习/内网可用;公网 API 建议改成 明确域名白名单,并结合业务评估是否必须 |
十一、一句话总结
这段 CorsConfig 的含义可以概括为:
对本服务几乎所有路径开放跨域访问;允许常见 HTTP 方法(含 OPTIONS 预检);允许任意请求头、暴露响应头;并允许浏览器在跨域场景下携带 Cookie 等凭证;来源暂时放行任意站点(
*)。
结语: 跨域配置是前后端分离项目的「标配」之一。理解 CORS 是浏览器行为、分清开发环境与生产环境的风险,再选择合适的来源白名单,才能既方便调试又保证安全。
更多推荐




所有评论(0)