🎯 核心概念

同源策略是浏览器的安全基石,像小区的围墙,默认隔离不同来源的资源,保护用户数据不被恶意网站窃取。

什么是“同源”?

三要素必须完全一致

⚡ 关键机制

判断时机:实时检查

同源判断发生在敏感操作执行的瞬间,不是预先分类:

1
2
3
4
5
6
7
8
// 示例1:网络请求
fetch("https://api.other-site.com/data"); // ⚠️ 在此刻判断!

// 示例2:DOM访问
iframe.contentDocument; // ⚠️ 在此刻判断!

// 示例3:存储访问
localStorage.getItem("key"); // 自动关联当前源

重要特性:脚本继承源

1
2
<!-- 在 https://my-site.com 中 -->
<script src="https://cdn.other-site.com/library.js"></script>
  • 脚本一旦加载执行,就继承当前页面源
  • ✅ 获得与本地脚本完全相同的权限
  • ⚠️ 这意味着主动信任:必须谨慎选择第三方脚本

🚫 受限制的操作

操作类型 限制说明 解决方案
DOM 访问 不能访问跨域 iframe 的 DOM postMessage
网络请求 默认阻止跨域 Ajax/Fetch CORS、代理服务器
数据存储 不能读取跨域 Cookie/LocalStorage -

✅ 允许的跨域嵌入

以下资源可以跨域加载,但不能读取内容

  • <img src="跨域图片">
  • <script src="跨域JS">
  • <link rel="stylesheet" href="跨域CSS">
  • <iframe src="跨域页面">

🔓 合法的跨域解决方案

1. CORS(主流推荐)

服务器设置响应头授权:

1
2
Access-Control-Allow-Origin: https://my-site.com
Access-Control-Allow-Methods: GET, POST

2. postMessage(窗口通信)

1
2
3
4
5
6
7
8
// 发送方
otherWindow.postMessage("数据", "https://目标源.com");

// 接收方
window.addEventListener("message", (event) => {
if (event.origin !== "https://可信源.com") return;
// 处理数据
});

3. 代理服务器

让同源服务器转发请求,绕过浏览器限制。

4. JSONP(已过时)

利用<script>标签跨域能力,仅限 GET 请求。

🛡️ 安全最佳实践

第三方脚本安全

1
2
3
4
5
6
<!-- 使用SRI完整性校验 -->
<script
src="https://cdn.com/library.js"
integrity="sha384-..."
crossorigin="anonymous"
></script>

CORS 精细控制

1
2
3
Access-Control-Allow-Origin: https://特定域名.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST

💡 核心要点总结

  1. 同源判断 = 实时检查:在操作发生时比对协议、域名、端口
  2. 脚本信任模型:外部脚本执行即获得当前源全部权限
  3. 默认禁止,按需授权:安全第一,通过 CORS 等机制开放必要权限
  4. 嵌入 ≠ 访问:可以加载跨域资源,但不能读取其内容