主题
同源策略
浏览器实施同源策略(Same-Origin Policy,SOP)的核心目的是保障用户隐私和数据安全,防止恶意网站通过跨域请求窃取或篡改敏感信息。
一、同源策略的定义与判定标准
同源的定义
两个 URL 的以下三要素必须完全一致才能视为同源:
- 协议(如 HTTP/HTTPS)
- 域名(包括子域名,如
www.example.com
与api.example.com
不同源)。 - 端口(默认端口可省略,如HTTP默认
80
端口、HTTPS 默认443
端口)。
例外情况
即使跨域,以下资源加载不受限制(但脚本无法直接操作内容):
<img>
、<script>
、<link>
等标签加载的静态资源(如图片、JavaScript、CSS)<iframe>
加载的页面(但无法通过 JavaScript 访问其 DOM)
二、同源策略的具体限制
DOM访问隔离
跨域页面间无法通过 JavaScript 互相操作 DOM。
例如,a.com
的脚本无法读取 b.com
页面的表单内容或元素属性。
数据存储隔离
Cookie
:仅允许同源页面访问(除非设置domain属性为父域名)。LocalStorage
、IndexDB
:完全禁止跨域访问。
网络请求拦截
AJAX/Fetch
请求:默认禁止跨域,浏览器会返回CORS错误。 -WebSocket
:不受同源策略限制,但需服务器显式允许连接。
跨窗口通信限制
不同源的窗口或框架间无法直接通过 window.postMessage()
以外的API通信。
三、绕过同源策略的安全方法
尽管同源策略严格,但合法场景下的跨域交互可通过以下方式实现:
CORS(跨域资源共享)
- 原理:服务器通过响应头(如
Access-Control-Allow-Origin
)声明允许的源、方法和头信息。 - 流程:
- 简单请求:直接发送请求,依赖服务器响应头授权(如 GET/POST 且无特殊头)。
- 预检请求(OPTIONS):非简单请求(如 PUT/DELETE 或自定义头)需先发送预检请求验证权限。
- Nginx配置示例:
nginx
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
return 204;
}
add_header 'Access-Control-Allow-Origin' '*';
}
(注:生产环境应替换 * 为具体域名以提升安全性)
JSONP(JSON with Padding)
跨域脚本调用。
- 原理:利用
<script>
标签不受同源策略限制的特性,动态插入脚本并通过回调函数获取数据。 - 局限性:仅支持 GET 请求,且需服务器返回包裹回调函数名的响应(如
callback(data)
)。
代理服务器
- 实现:通过同源的后端服务(如 Nginx)转发请求,隐藏真实跨域目标。
- 示例:前端请求
/api/data
,Nginx 代理转发至backend-server:8081/api/data
。
postMessage API
- 用途:安全实现跨窗口通信(如父子页面间传递消息)。
- 安全建议:始终验证消息来源(
event.origin
)并限制目标窗口。
四、同源策略的安全意义
- 防御XSS/CSRF攻击:阻止恶意脚本窃取用户会话Cookie或伪造请求。
- 隔离敏感数据:确保不同域的数据存储(如银行网站与社交网站)互不干扰。
- 平衡灵活性与安全:通过CORS等机制在安全前提下支持合法跨域需求。
总结
浏览器通过同源策略构建了基础安全防线,开发者需理解其限制并通过 CORS 等可控方式实现跨域交互。合理配置服务器响应头(如 Access-Control-Allow-Origin
)是解决跨域问题的核心,同时需避免过度开放权限(如滥用通配符 *
)以降低安全风险。