浏览器同源策略:从“源”到安全限制的全面解析
一、什么是“源”(Origin)?
在浏览器中,“源”是 Web 安全的核心概念。一个“源”由三部分组成:
-
协议(Protocol):如
http://
、https://
、ftp://
-
域名(Host):如
www.example.com
-
端口(Port):如
:80
(HTTP 默认)、:443
(HTTPS 默认)
示例:
-
https://www.example.com:443
和https://www.example.com
是同源(端口隐式相同)。 -
http://blog.example.com
和https://www.example.com
是不同源(协议、子域名不同)。
二、同源与异源(Cross-Origin)的定义
-
同源(Same Origin):两个 URL 的协议、域名、端口完全一致。
-
异源(Cross-Origin):任意一部分不同即为异源。
判断示例:
URL1 | URL2 | 是否同源 |
---|---|---|
https://a.com/index.html | https://a.com/api | ✅ 是 |
https://a.com:8080 | https://a.com(浏览器默认端口443) | ❌ 否 |
http://a.com | https://a.com | ❌ 否 |
三、同源策略(Same-Origin Policy)是什么?
同源策略是浏览器强制实施的安全机制,核心规则是:
默认禁止跨源脚本访问其他源的资源,除非明确授权。
设计目标:
-
防止恶意网站窃取用户数据(如 Cookie)。
-
阻止跨站脚本攻击(XSS、CSRF)。
四、浏览器如何限制异源操作?
浏览器对跨源行为的限制体现在以下场景:
1. DOM 访问限制
规则:禁止通过 JavaScript 访问跨源页面的 DOM。
示例:
// 父页面尝试获取跨域 iframe 的内容
const iframe = document.getElementById('cross-origin-iframe');
const iframeDoc = iframe.contentWindow.document; // 抛出安全错误
2. 网络请求限制
-
AJAX/Fetch:默认禁止跨域请求(除非目标服务器返回 CORS 头)。
-
错误提示:
Access to fetch at 'https://api.other.com' from origin 'https://www.example.com' has been blocked by CORS policy.
3. 存储数据隔离
-
Cookie/LocalStorage:仅允许同源页面访问。
-
示例:
https://malicious.com
无法读取https://bank.com
的登录 Cookie。
4. 特殊资源的加载限制
-
图片/音视频:允许跨域加载,但通过
<canvas>
操作跨域图片会污染画布(tainted)。 -
脚本/CSS:允许加载,但浏览器会隐藏跨域脚本的详细错误信息(避免信息泄露)。
五、跨源限制的例外与解决方案
1. CORS(跨源资源共享)
-
原理:服务器通过响应头(如
Access-Control-Allow-Origin: *
)声明允许的源。 -
适用场景:AJAX、Fetch 等复杂请求。
2. JSONP
-
原理:利用
<script>
标签的跨域特性,通过回调函数获取数据。 -
缺点:仅支持 GET 请求,存在安全风险。
3. postMessage API
-
用途:实现跨域 iframe 或窗口之间的安全通信。
-
示例:
javascript
复制
// 父页面向跨域 iframe 发送消息 iframe.contentWindow.postMessage('Hello', 'https://other.com');
4. 代理服务器
-
原理:将跨域请求转发到同源的后端服务器,由服务器代为请求。
-
适用场景:无法修改目标服务端 CORS 配置时。
六、为什么同源策略如此重要?
-
用户隐私保护:防止恶意网站窃取其他站点的用户会话(如银行 Cookie)。
-
数据完整性:阻止跨站请求伪造(CSRF)攻击。
-
安全沙盒:为每个源建立独立的运行环境,限制攻击面。
扩展阅读:
-
MDN - 同源策略
-
CORS 完全指南
-
前端安全:XSS 与 CSRF 攻防