Web-Tech:CORS的触发机制

22 阅读3分钟

触及了CORS的核心机制 细解释其中的关键区别:

关键区别:浏览器导航 vs JavaScript API请求

1. 描述的情况(Google搜索结果):

点击Google搜索结果中的链接时,发生的是:

  • 浏览器导航:浏览器地址栏直接变成 https://abcnews.go.com/
  • 整个页面被替换:浏览器完全离开Google,加载ABC News的页面
  • 这不是跨源请求:这是用户主动的页面跳转,浏览器允许这种行为

2. CORS限制的情况:

JavaScript代码在一个页面中尝试异步获取另一个域的资源时:

  • 页面不跳转:仍然在Google页面上
  • JavaScript悄悄获取数据:JS试图在后台获取 https://abcnews.go.com/ 的数据
  • 浏览器阻止:因为这会带来安全风险(网站可以偷偷读取其他网站数据)

用现实世界做类比

类比1:图书馆查询系统(类似Google搜索)

  • 合法行为:通过图书馆系统查到了《纽约时报》的文章索引
  • 点击查看离开图书馆系统,直接去《纽约时报》网站阅读全文 ✅
  • 非法行为:让图书馆系统自动复制《纽约时报》的全部内容到图书馆网站上 ❌

类比2:新闻报道引用

  • 合法引用:报道中说"据《华尔街日报》报道...",读者点击链接去看原文 ✅
  • 非法抄袭:报道中直接把《华尔街日报》的全文数据嵌入到自己的网站中 ❌

技术层面的明确区分

允许的(不会触发CORS):

<!-- 用户点击链接 -->
<a href="https://abcnews.go.com/article">点击前往ABC News</a>

<!-- 用户提交表单 -->
<form action="https://other-site.com/submit" method="GET">

会触发CORS的:

// JavaScript试图在后台获取其他网站的数据
fetch("https://abcnews.go.com/api/data")  // 会触发CORS检查
  .then(response => response.json())
  .then(data => {
    // 将ABC News的数据显示在Google页面上
    document.getElementById("content").innerHTML = data;
  });

为什么浏览器要这样设计?

安全风险示例:

假设恶意网站 evil.com 可以任意读取其他网站的数据:

  1. 登录网上银行 bank.com
  2. 在另一个标签页打开了 evil.com
  3. evil.com 的JavaScript可以:
    // 悄悄获取银行余额(如果允许跨域)
    fetch("https://bank.com/api/balance")
      .then(data => sendToHackerServer(data));
    

同源策略的保护:

  • 隔离数据:每个网站的JavaScript只能访问自己网站的数据
  • 用户知情:跨域数据访问需要目标网站的明确同意(CORS头)
  • 防止CSRF:防止其他网站冒充用户发起请求

实际示例对比

示例A:正常的网页跳转 ✅

<!-- Google搜索结果页面 -->
<body>
  <h1>搜索结果</h1>
  <a href="https://news.bbc.co.uk">BBC News</a>  <!-- 用户点击这里 -->
  <a href="https://www.nytimes.com">New York Times</a>
</body>

结果:用户离开Google,进入BBC网站

示例B:会触发CORS的请求 ❌

<!-- Google搜索结果页面 -->
<body>
  <h1>搜索结果</h1>
  <div id="news-content">正在加载BBC新闻...</div>
  
  <script>
    // 尝试在Google页面上直接显示BBC的内容
    fetch("https://news.bbc.co.uk/latest-news")  // CORS错误!
      .then(response => response.text())
      .then(html => {
        document.getElementById("news-content").innerHTML = html;
      });
  </script>
</body>

特别说明:iframe的中间情况

<!-- 在Google页面中嵌入BBC -->
<iframe src="https://news.bbc.co.uk"></iframe>
  • 允许:可以嵌入其他网站
  • 限制:Google的JavaScript不能访问iframe中BBC的内容
  • 隔离:两个网站的JavaScript完全隔离

总结困惑

  1. Google搜索到ABC News的链接:用户点击 → 页面跳转 → 不是CORS场景
  2. APK列表页面:JavaScript在后台fetch数据 → 是CORS场景
  3. CORS只限制:JavaScript的fetch()XMLHttpRequestaxios等API调用
  4. CORS不限制<a>链接点击、<form>提交、<iframe>加载、<script>标签加载、<img>加载等

简单记忆

  • 用户主动操作(点击链接):✅ 允许
  • JavaScript偷偷操作(ajax请求):❌ 需要CORS授权

这就是为什么不需要CORS插件就能浏览网页,但需要它来开发前端应用的原因