[toc]
| 单词 | 词性 | 音标 | 含义 |
|---|---|---|---|
| CORS | n. | /kɔːz/ | 跨域资源共享,后端加响应头告知浏览器放行 |
| origin | n. | /ˈɒrɪdʒɪn/ | 源,由协议 + 域名 + 端口组成,任一不同即跨域 |
| CrossOrigin | n. | /krɒs ˈɒrɪdʒɪn/ | SpringMVC 注解,允许某个接口或控制器跨域 |
| Access-Control-Allow-Origin | n. | /ˈækses kənˈtrəʊl əˈlaʊ ˈɒrɪdʒɪn/ | 响应头,声明允许访问的来源 |
| preflight | n. | /ˈpriːflaɪt/ | 预检请求(OPTIONS),复杂请求前浏览器先探路 |
| Network | n. | /ˈnetwɜːk/ | 开发者工具的 Network 面板,用于验证跨域是否解决 |
| MVC | n. | /ˌem viː ˈsiː/ | SpringMVC,后端框架,CORS 配置的落脚点 |
Lecture20-跨域与 CORS 专题:前后端联调
1、本节讲什么
彻底搞懂"前端调后端接口被浏览器拦截"这件事,并学会在**后端(SpringMVC)**配置 CORS 解决它。

2、概念速览
什么是跨域:前端页面地址和它请求的接口地址,"协议 / 域名 / 端口"任一不同,就叫跨域。浏览器出于安全会拦截。
什么是 CORS:后端在响应里加"允许哪些来源访问"的响应头,告诉浏览器"这个接口我放行"。

关键认知:跨域是浏览器的安全规则,不是后端拒绝你;解决开关在后端,前端做不了主。
正确 vs 误区:别以为前端能"关掉"跨域——开关在后端响应头;前端能做的是代理(开发期)和排查。
先说结论(记住这一句)
跨域是浏览器的安全规则,不是后端拒绝你。解决方法是后端在响应里加允许跨域的响应头(CORS),前端无法靠自己彻底解决,但能配合。
① 什么是跨域、为什么报错
跨域 = 前端页面所在的地址,和它请求的接口地址,"协议 / 域名 / 端口"任一不同就算跨域。
| 前端页面地址 | 请求的接口地址 | 是否跨域 |
|---|---|---|
http://localhost:5173 | http://localhost:5173/api/x | 否(同源) |
http://localhost:5173 | http://localhost:8080/api/x | 是(端口不同) |
http://a.com | http://b.com/api/x | 是(域名不同) |
浏览器发现跨域,会先发一个"预检"请求,后端若没在响应里说"我允许这个来源访问",浏览器就把真正的请求拦截,控制台报错类似:
Access to XMLHttpRequest at 'http://localhost:8080/api/users'
from origin 'http://localhost:5173' has been blocked by CORS policy
② 后端怎么解决(SpringMVC 三套写法,任选其一)
写法一:单个接口加注解 @CrossOrigin
@RestController
@RequestMapping("/api/users")
public class UserController {
@CrossOrigin // 允许所有来源访问这个接口
@GetMapping
public List<User> list() { ... }
}
写法二:整个 Controller 加注解
@CrossOrigin
@RestController
@RequestMapping("/api/users")
public class UserController { ... }
写法三:全局配置类(推荐,一次性管所有接口)
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 所有接口都允许
.allowedOrigins("*") // 允许的来源(生产可限定成你的域名)
.allowedMethods("*") // 允许的方法(GET/POST/PUT/DELETE...)
.allowedHeaders("*"); // 允许的请求头
}
}
开发期图省事用
*;生产环境建议把allowedOrigins改成你的真实前端域名,更安全。
③ 前端配合:看 Network 验证是否已解决
- 触发一次接口请求。
- 打开开发者工具 → Network → 点那条请求 → Headers。
- 如果响应头里有
Access-Control-Allow-Origin,说明后端 CORS 配置已生效,问题解决。 - 若没有,说明后端没配好,回去检查上面三套写法。
④ 前端能做和不能做的
- 能:通过 Vite 代理(仅开发期,第 19 节)绕过。
- 能:把报错截图/原文交给后端同学或 AI,明确"是跨域"。
- 不能:靠前端代码"关掉"跨域。跨域的开关在后端。
5、常见疑问
- Q:为什么后端配了 CORS,前端还是报错?
A:① 改完代码要重启后端;②
allowedOrigins("*")在带 cookie 的请求上会被浏览器拒绝(需要指定具体来源);③ 代理没配对。按 ③ 的 Network 三步查。 - Q:
allowedOrigins("*")和指定域名有什么区别? A:*允许任何网站访问你的接口;指定域名只允许那一个。生产用指定域名更安全。 - Q:post 请求报跨域,get 不报,为什么? A:浏览器对复杂请求(带 JSON 体、自定义头)会先发"预检",更容易被拦。检查预检请求(Network 里 OPTIONS 开头的那条)是否也被允许。
- Q:生产环境(部署后)跨域怎么办?
A:生产没有 Vite 代理,只能靠后端 CORS(写法三的全局配置),并且
allowedOrigins填前端真实域名。
6、规范要点
- 跨域问题的判断先看 Network,别上来就怀疑代码——90% 是后端 CORS 没配或没重启。
- 开发期用代理、生产期用 CORS,两条路都掌握。
- 把"CORS 报错原文 + 是哪个接口 + 期望效果"整理好再去找 AI / 后端,别人才能秒懂(这也是第 39 节的方法)。
7、本节验证
- 能判断“协议 / 域名 / 端口任一不同”即跨域 ✅
- 知道跨域是浏览器规则、开关在后端响应头 ✅
- 会用 SpringMVC 三套写法之一配置 CORS(@CrossOrigin / 全局配置类) ✅
- 会打开 Network 看 Access-Control-Allow-Origin 验证是否解决 ✅
- 知道前端能用开发代理绕、但不能靠自己关掉跨域 ✅