JavaScript的同源策略
JavaScript 的同源策略(Same-Origin Policy) 是浏览器最核心的安全机制之一,目的是防止恶意网站通过脚本或请求窃取用户数据或发起攻击。它的核心规则是:浏览器只允许脚本访问与当前页面「同源」的资源。
一、什么是「同源」?
两个 URL 的以下三个部分必须完全一致:
- 协议(Protocol,如
httpvshttps) - 域名(Domain,如
example.comvssub.example.com) - 端口(Port,如
80vs8080,默认端口可省略)
示例:
| 当前页面 URL | 目标 URL | 是否同源 | 原因 |
|---|---|---|---|
https://example.com/a | https://example.com/b | ✅ | 协议、域名、端口均一致 |
http://example.com | https://example.com | ❌ | 协议不同(HTTP vs HTTPS) |
https://example.com | https://api.example.com | ❌ | 域名不同(主域 vs 子域) |
https://example.com:80 | https://example.com:443 | ❌ | 端口不同 |
二、同源策略的限制范围
-
AJAX / Fetch 请求
- 默认禁止跨域请求(如
fetch("https://api.other.com")会被浏览器拦截)。 - 需通过 CORS 或代理等方式解决。
- 默认禁止跨域请求(如
-
DOM 访问
- 禁止跨域访问
iframe或新窗口的内容(如window.parent.document)。
- 禁止跨域访问
-
Web 存储
Cookie、LocalStorage、IndexedDB仅允许同源访问。
-
其他资源加载
- 虽然
<img>、<script>、<link>等标签允许跨域加载资源(如 CDN 引用),但无法直接读取跨域资源的内容(例如通过 JavaScript 读取跨域图片的像素数据)。
- 虽然
三、如何绕过同源策略?
- CORS(跨域资源共享)
- 原理:服务器在响应头中声明允许的跨域来源。
- 实现:
Access-Control-Allow-Origin: https://your-site.com # 允许特定源 Access-Control-Allow-Origin: * # 允许所有源(慎用!) - 复杂请求(如 POST 带自定义头):需预检(Preflight)请求(
OPTIONS方法)。
- JSONP(仅限 GET 请求)
-
原理:利用
<script>标签不受同源策略限制的特性,通过回调函数接收数据。 -
示例:
<script src="https://api.other.com/data?callback=handleData"></script>function handleData(data) { console.log("Received:", data); }
- 代理服务器
- 原理:通过同源的后端服务器转发跨域请求(如 Nginx 或 Node.js 代理)。
- 适用场景:无法修改目标服务器(如第三方 API)时使用。
- postMessage API
- 原理:允许跨域的窗口间通过消息传递通信。
- 示例:
// 发送消息到其他窗口 otherWindow.postMessage("Hello!", "https://other-site.com"); // 接收消息 window.addEventListener("message", (event) => { if (event.origin === "https://other-site.com") { console.log("Received:", event.data); } });
- WebSocket
- 原理:WebSocket 协议默认支持跨域通信(但服务器需验证
Origin头)。
四、注意事项
- 安全风险:过度放宽跨域限制(如
Access-Control-Allow-Origin: *)可能导致 CSRF 或数据泄露。 - Cookie 跨域:需设置
withCredentials: true(前端)和Access-Control-Allow-Credentials: true(服务端)。 - 现代浏览器限制:默认禁止跨域的
document.cookie、LocalStorage访问,即使域名相同但协议或端口不同也会被拦截。
总结
同源策略是浏览器安全的基石,但合理使用 CORS、代理、postMessage 等技术可实现安全的跨域通信。开发中需根据场景选择方案,并始终遵循最小权限原则,避免安全漏洞。
更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github