Appearance
同源策略
元信息
- 目标:理解同源策略为何是浏览器的地基式安全边界——脚本可自由发请求后必须防"跨源读取";掌握"同源"的判定(协议/域名/端口)与 CORS 受控放开的机制,跨域报错时知道该找谁
- 关键概念:同源策略、协议/域名/端口、跨源、CORS、Access-Control-Allow-Origin、预检请求(OPTIONS)、代理
- 关联阶段:cp3
- 常见误区:以为跨域是"请求发不出去"(请求已发出,是响应被浏览器拦下不让脚本读);以为 CORS 能在前端单方面解决(开关在服务端手里,前端只能靠服务端配合或代理);以为 img/script 等标签跨源加载也被禁(同源策略限制的是"读",传统标签嵌入本就可跨源,CDN 正因此工作)
为什么会有同源策略?
ajax 让脚本能自由发请求——如果没有任何限制,你银行标签页里的脚本(或注入的恶意脚本)就可以悄悄向你的邮箱、公司内网发请求并读取响应。浏览器里存放着最私密的资源(cookie、登录态、内网页面),同源策略(Same-Origin Policy)就是浏览器的地基式安全边界:没有它,整个 Web 都无法安全登录任何网站。
规则:什么算"同源"
两个 URL 的 协议、域名、端口 三者全部相同,才算同源:
| URL | 相对 https://x.com/posts | 是否同源 |
|---|---|---|
https://x.com/comments | 路径不同 | ✅ 同源 |
http://x.com/posts | 协议不同 | ❌ |
https://api.x.com/posts | 域名不同 | ❌ |
https://x.com:8080/posts | 端口不同 | ❌ |
策略限制了什么,不限制什么
- 限制的是"读":跨源的 ajax/fetch 请求可以发出,但响应默认对脚本不可读(写Cookie类请求还受更多约束)
- 不限制:
<img>、<script>、<link>、<form>提交等传统标签的跨源加载——它们本来就可以跨源嵌入资源(这也是 CDN 工作的原理,见第 7 周);只是脚本读不到跨源图片、样式的内容 - 换言之:同源策略防的是"拿到并读取数据",不是"发出请求"
CORS:受控地放开
实际应用中前端与服务端 API 常常不同源(如 x.com 调 api.x.com),放开的方式是 CORS(跨源资源共享)——一套由服务端声明、浏览器执行的放行规则:
http
# 服务端在响应头中声明:我允许 http://x.com 读取本响应
Access-Control-Allow-Origin: https://x.com- 简单请求:浏览器直接发出,检查响应头有无放行声明
- 非简单请求(如带自定义头、
PUT/DELETE):浏览器先发一个OPTIONS预检请求询问服务端是否放行,通过后才发正式请求 - 关键认知:CORS 的开关在服务端手里——前端"解决跨域"只能靠服务端配合或代理(如开发期 vite/webpack 的 devServer proxy),这是多数初学者的第一个误区
与 json-server 实训的关系
前端跑在 :5500(live server)、json-server 跑在 :3000——端口不同即跨源。实训中接口能通,正是因为 json-server 默认开启了 CORS(返回 Access-Control-Allow-Origin: *)。见实训:restful后端。