跨域解析
2026/1/17大约 3 分钟
跨域解析
什么是"源"(Origin)?
源 = 协议 + 域名 + 端口
http://localhost:5173 ← 前端(Vite)
http://localhost:8081 ← 后端(Spring Boot)
↑ ↑
协议 端口不同 → 不同源 → 跨域!为什么有跨域限制?
这是浏览器的安全机制,叫做同源策略。
想象一个恶意场景:
- 你登录了银行网站
bank.com,Cookie 里有你的身份凭证 - 你访问了恶意网站
evil.com - 恶意网站的 JS 代码尝试请求
bank.com/transfer?to=hacker&amount=10000 - 如果没有同源策略,请求会自动携带 Cookie,钱就被转走了!
同源策略阻止了这种攻击:浏览器不允许 evil.com 的 JS 读取 bank.com 的响应。
不做跨域处理时的请求流程
sequenceDiagram
participant 浏览器
participant 前端JS
participant 后端API
前端JS->>浏览器: fetch("http://localhost:8081/auth/login")
Note over 浏览器: 检测到跨域!<br/>目标源 ≠ 当前页面源
浏览器->>后端API: OPTIONS /auth/login (预检请求)
后端API-->>浏览器: 200 OK (但没有 CORS 响应头)
Note over 浏览器: ❌ 没有 Access-Control-Allow-Origin 头<br/>拒绝后续请求!
浏览器-->>前端JS: Network Error
Note over 前端JS: 请求被浏览器拦截<br/>根本没发出实际请求关键点:
- 请求确实发到了后端(预检请求)
- 后端确实返回了响应
- 但浏览器检查响应头,没找到允许跨域的标记
- 浏览器阻止 JS 代码读取响应,抛出 Network Error
[!WARNING] > 是浏览器拦截,不是后端拒绝! 用 Postman/curl 请求同样的 API 完全正常。
做了跨域处理后的请求流程
sequenceDiagram
participant 浏览器
participant 前端JS
participant CorsFilter
participant Controller
前端JS->>浏览器: fetch("http://localhost:8081/auth/login")
Note over 浏览器: 检测到跨域!发预检请求
浏览器->>CorsFilter: OPTIONS /auth/login
Note over CorsFilter: 添加 CORS 响应头
CorsFilter-->>浏览器: 200 OK + CORS Headers
Note over 浏览器: ✅ 检查通过!<br/>Access-Control-Allow-Origin: *
浏览器->>CorsFilter: POST /auth/login (实际请求)
CorsFilter->>Controller: 转发请求
Controller-->>CorsFilter: 返回登录结果
CorsFilter-->>浏览器: 响应 + CORS Headers
浏览器-->>前端JS: { accessToken: "xxx" }
Note over 前端JS: ✅ 成功获取数据关键的 CORS 响应头:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:5173 ← "我允许这个源访问"
Access-Control-Allow-Methods: GET, POST, PUT, DELETE ← "我允许这些方法"
Access-Control-Allow-Headers: Content-Type, Authorization ← "我允许这些请求头"
Access-Control-Allow-Credentials: true ← "我允许携带 Cookie/Token"浏览器看到这些响应头,就知道后端明确授权了这个跨域请求。
一句话总结
| 场景 | 结果 |
|---|---|
| 无 CORS 配置 | 后端返回数据,但浏览器拦截 → JS 拿不到 |
| 有 CORS 配置 | 后端返回数据 + CORS 头,浏览器放行 → JS 拿到数据 |
[!TIP] > 核心原理:CORS 是后端告诉浏览器"我信任这个来源",浏览器才会把响应交给 JS 代码。
