~/app/articles/NORMAL

cat article/19.md

“跨域连接”:当浏览器化身尽责的“守门人”

技术开发(前端)
跨域连接
同源策略
浏览器安全
JavaScript
前端开发

本文探讨了浏览器中的“跨域连接”问题,解释了同源策略(SOP)如何限制不同源之间的资源访问,并说明了这一安全策略在保护网页安全中的作用。

date: 2025-07-28T23:53:00
author: 黄应辉


“跨域连接”:当浏览器化身尽责的“守门人”

想象一下,你正在浏览一个设计精美的新闻网站 www.news-site.com。这个网站的页面上,有一段加载评论区的 JavaScript 代码。这段代码想直接访问另一个网址 api.comments-service.com 来获取最新的评论数据。乍一看,这似乎很合理:新闻页面需要显示评论嘛。但在浏览器的世界里,这个看似简单的动作却会​​碰壁​​。原因就在于——www.news-site.com 和 api.comments-service.com 属于两个​​不同的“源”(Origin)​​。所谓“跨域连接”,指的就是浏览器中,一个源(比如页面来自哪里)的代码试图与另一个源的资源(比如数据、图片、接口)建立连接的行为。

为什么源不同就有问题呢?这源于浏览器的一项核心安全策略——“​​同源策略​​(Same-Origin Policy, SOP)”。它对“源”的判定非常严格:协议 (http:// 或 https://)、完整域名(包括子域名)、端口号,三者必须​​完全相同​​。例如:

  • https://www.news-site.com 和 http://www.news-site.com ​​不同源​​(协议不同,https vs http)。
  • https://www.news-site.com 和 https://api.news-site.com ​​不同源​​(域名不同,www. vs api.)。
  • https://www.news-site.com 和 https://www.news-site.com:8080 ​​不同源​​(端口不同,默认443 vs 8080)。

浏览器执行SOP就像一个尽责的守门人。当我们新闻页面里的 JavaScript (www.news-site.com) 试图调用评论服务的 API (api.comments-service.com) 时,这个守门人立刻警觉了:“等等!你是 www.news-site.com 的人,却想拿 api.comments-service.com 的东西?除非那边的老板明确点头,否则我不能放行。” 后果就是,浏览器会​​阻止页面上的 JavaScript 代码获取到那个API返回的实际数据​​。

案例一:张三的评论列表加载失败
小张同学正在开发新闻网站的前端。他写好了代码,使用 fetch() API 去请求 api.comments-service.com/comments。代码运行了,在浏览器的开发者工具“网络”(Network)标签下,他甚至能看到这个请求发送出去了,并且服务器也正确返回了评论数据(状态码200)。​​但诡异的是,他精心编写的处理回复数据的JavaScript代码就是拿不到返回的评论!​​ 控制台还会出现一个刺眼的错误:“Access to fetch at https://api.comments-service.com/comments from origin https://www.news-site.com has been blocked by CORS policy...”。这就是跨域连接的​​直接后果​​——请求可以发出去,但响应被浏览器拦截了,代码读不到数据。他的评论区一片空白,功能彻底失效。

sequenceDiagram
    participant Browser as 浏览器 (news-site.com页)
    participant Server as 评论API服务器(comments-service.com)
    Browser->>Server: 发送 GET /comments 请求 <br> (附带 Origin: https://www.news-site.com)
    Server-->>Browser: 返回评论数据 (200 OK) <br> (但缺少 CORS 响应头)
    Browser-->>Browser: 检测到响应头缺少 Access-Control-Allow-Origin <br> 且 Origin 不被许可 -> 阻止数据传递给JS!
Mermaid diagram source. A rendered diagram replaces this fallback when available.

案例二:李四的图片防盗链成功
电商网站 shop.com 为了防止别人直接盗用他们服务器上的商品图片链接 (俗称​​盗链​​),正是利用了同源策略。如果另一个网站 competitor.com 的页面上直接用 标签引用 `https://img.shop.com/products/123.jpg`,当用户访问 `competitor.com` 时,浏览器就会向 `img.shop.com` 请求这张图片。`img.shop.com` 的服务器可以检测到请求头中的 `Origin` (或 `Referer`) 是 `competitor.com`。如果 `img.shop.com` **没有明确配置允许 `competitor.com` 访问**(即没有CORS支持),那么**浏览器最终可能允许显示图片(因为标签有特殊宽松规则),或者如果服务器发现盗链直接返回403错误图片,浏览器也会显示错误图,导致竞争对手网站上的商品图无法正常显示​**​。这就达到了防盗链的目的。

那么,合法的跨域需求(如我们的新闻站想加载评论)该如何实现呢?这就是 ​​CORS (跨域资源共享, Cross-Origin Resource Sharing)​​ 的舞台。它的核心思想是:服务器拥有资源的控制权,它可以通过在响应中添加特定的​​HTTP头部​​来明确声明哪些​​外部的源​​是被允许来访问其资源的。

当新闻站点 (www.news-site.com) 的JavaScript再次尝试请求评论API (api.comments-service.com) 时,会发生:

  1. ​​浏览器发送请求​​时,会自动添加一个 Origin: https://www.news-site.com 头。
  2. ​​评论API服务器​​收到请求,检查 Origin 头。
  3. ​​服务器同意放行​​:服务器需要在返回的响应头中添加关键信息:
    • Access-Control-Allow-Origin: https://www.news-site.com (精确匹配) 或者 Access-Control-Allow-Origin: * (允许任何源访问,风险高,不推荐用于敏感数据或含认证信息的请求)。
    • (对于非简单请求,如 POST 带自定义头或非标准内容类型,浏览器会先自动发一个 OPTIONS “预检”请求,服务器也需要正确响应,用 Access-Control-Allow-Methods 声明允许的HTTP方法,Access-Control-Allow-Headers 声明允许的请求头等)。
  4. ​​浏览器收到响应​​:它检查响应中是否包含 Access-Control-Allow-Origin 头,以及这个头的值是否匹配本次请求的 Origin 或者允许所有 (*)。
  5. ​​放行​​:如果匹配成功,浏览器解除限制,允许页面上的JavaScript代码读取响应数据。
sequenceDiagram
    participant Browser as 浏览器 (news-site.com页面)
    participant Server as 评论API服务器 (comments-service.com)
    Browser->>Server: GET /comments <br> Origin: https://www.news-site.com
    Server-->>Browser: 200 OK <br> Access-Control-Allow-Origin: https://www.news-site.com <br> ... <br> [评论数据]
    Browser-->>Browser: 检测到响应头包含 Access-Control-Allow-Origin <br> 且值匹配当前 Origin -> 允许JS读取数据!
    Browser->>Page JS: 返回评论数据
Mermaid diagram source. A rendered diagram replaces this fallback when available.

于是,小张同学只需要让评论服务的后端开发同事在API的响应配置中添加正确的 Access-Control-Allow-Origin 头(指向 https://www.news-site.com),他的前端代码就能顺利加载评论数据了。而李四的电商图片,如果没有为竞争对手配置 CORS,防盗链策略就能有效保护图片资源。

总的来说,“跨域连接”本身是描述一种常见行为,但它在浏览器中遭遇的​​后果直接由同源策略(SOP)决定​​:​​安全第一,默认禁止​​。CORS 机制则提供了一把​​安全的钥匙​​,让服务器能主动管理这把锁,在确保安全可控的前提下,优雅地解决现代 Web 应用对跨域协作的刚需。下次当你在开发中遇到那个经典的 CORS 错误时,不妨想想这位尽责的“守门人”——它看似制造了麻烦,却守护着网络世界的基础安全秩序。

$ comments --list (0)

// not signed in


// no comments yet