Web安全之同源策略与跨域解决方案进阶
字数 1929 2025-11-06 12:41:20

Web安全之同源策略与跨域解决方案进阶

一、同源策略的本质

同源策略是浏览器最核心的安全机制之一,它限制一个源的文档或脚本如何与另一个源的资源交互。

  • 同源的定义:协议、域名、端口完全相同。例如:
    • https://a.com/index.htmlhttps://a.com/api 同源(协议、域名、端口一致)。
    • https://a.comhttp://a.com 不同源(协议不同)。
  • 限制范围
    • Cookie/LocalStorage 访问
    • DOM 操作(如 iframe 嵌套)
    • AJAX 请求(实际可发送,但响应被浏览器拦截)

二、跨域解决方案的底层原理

1. JSONP(JSON with Padding)

原理:利用 <script> 标签不受同源策略限制的特性,通过动态创建脚本标签发起 GET 请求。
步骤

  1. 前端定义全局回调函数:
    function handleResponse(data) {  
      console.log(data);  
    }  
    
  2. 动态添加 <script> 标签:
    const script = document.createElement('script');  
    script.src = 'https://api.example.com/data?callback=handleResponse';  
    document.body.appendChild(script);  
    
  3. 服务端返回回调函数包裹的数据:
    handleResponse({ "status": "success", "data": ... });  
    

缺点:仅支持 GET 请求,缺乏错误处理机制。

2. CORS(跨域资源共享)

原理:服务端通过设置 HTTP 响应头显式允许某些源的请求。

  • 简单请求(直接触发 CORS):
    • 方法为 GET/POST/HEAD,Content-Type 为 application/x-www-form-urlencodedmultipart/form-datatext/plain
    • 浏览器自动在请求头添加 Origin: https://a.com,服务端需返回 Access-Control-Allow-Origin: https://a.com(或 *)。
  • 预检请求(需先发送 OPTIONS 请求):
    • 触发条件:自定义头(如 Authorization)、非简单 Content-Type(如 application/json)。
    • 浏览器先发送 OPTIONS 请求,服务端需响应:
      Access-Control-Allow-Origin: https://a.com  
      Access-Control-Allow-Methods: POST, GET  
      Access-Control-Allow-Headers: Content-Type  
      
  • 携带凭证(如 Cookie):
    • 前端设置 withCredentials: true,服务端需指定 Access-Control-Allow-Origin 为具体源(不能为 *),并返回 Access-Control-Allow-Credentials: true

3. 代理服务器

原理:将跨域请求转发至同源的服务端,由服务端代为请求目标接口。

  • 开发环境:Webpack DevServer 配置 proxy
    devServer: {  
      proxy: {  
        '/api': {  
          target: 'https://api.example.com',  
          changeOrigin: true  // 修改请求头中的 Origin 为目标地址  
        }  
      }  
    }  
    
  • 生产环境:通过 Nginx 反向代理:
    location /api/ {  
      proxy_pass https://api.example.com/;  
      proxy_set_header Host $host;  
    }  
    

4. postMessage

原理:允许不同源的窗口间通过消息事件通信。

// 发送方(https://a.com)  
iframe.contentWindow.postMessage('Hello', 'https://b.com');  

// 接收方(https://b.com)  
window.addEventListener('message', (event) => {  
  if (event.origin !== 'https://a.com') return;  
  console.log(event.data); // 'Hello'  
});  

5. document.domain(适用于子域跨域)

原理:将同一主域下的子域页面设置为相同域名。

  • 限制:仅适用于 a.example.comb.example.com 之间的跨域。
  • 代码:
    // 在两个页面中均设置  
    document.domain = 'example.com';  
    

三、方案对比与适用场景

方案 适用场景 优势 缺陷
JSONP 老旧浏览器兼容、简单 GET 请求 兼容性好 安全性低、仅支持 GET
CORS 现代浏览器、需灵活控制请求方法 前端无需改动、支持多种请求类型 需服务端配合
代理服务器 开发环境调试、避免服务端改动 前端无感知、可缓存请求 生产环境需部署代理中间件
postMessage 跨窗口通信(如微前端) 安全可控、支持复杂数据 需主动监听消息事件

四、安全注意事项

  1. CORS 的 Access-Control-Allow-Origin: * 需谨慎使用,避免敏感数据泄露。
  2. JSONP 的风险:可能被恶意注入脚本,需校验数据来源。
  3. 代理服务器需防范 SSRF 攻击(服务端请求伪造)。

通过理解同源策略的约束机制及各类跨域方案的底层原理,可根据实际场景选择最合适的安全解决方案。

Web安全之同源策略与跨域解决方案进阶 一、同源策略的本质 同源策略 是浏览器最核心的安全机制之一,它限制一个源的文档或脚本如何与另一个源的资源交互。 同源的定义 :协议、域名、端口完全相同。例如: https://a.com/index.html 与 https://a.com/api 同源 (协议、域名、端口一致)。 https://a.com 与 http://a.com 不同源 (协议不同)。 限制范围 : Cookie/LocalStorage 访问 DOM 操作(如 iframe 嵌套) AJAX 请求(实际可发送,但响应被浏览器拦截) 二、跨域解决方案的底层原理 1. JSONP(JSON with Padding) 原理 :利用 <script> 标签不受同源策略限制的特性,通过动态创建脚本标签发起 GET 请求。 步骤 : 前端定义全局回调函数: 动态添加 <script> 标签: 服务端返回回调函数包裹的数据: 缺点 :仅支持 GET 请求,缺乏错误处理机制。 2. CORS(跨域资源共享) 原理 :服务端通过设置 HTTP 响应头显式允许某些源的请求。 简单请求 (直接触发 CORS): 方法为 GET/POST/HEAD,Content-Type 为 application/x-www-form-urlencoded 、 multipart/form-data 或 text/plain 。 浏览器自动在请求头添加 Origin: https://a.com ,服务端需返回 Access-Control-Allow-Origin: https://a.com (或 * )。 预检请求 (需先发送 OPTIONS 请求): 触发条件:自定义头(如 Authorization )、非简单 Content-Type(如 application/json )。 浏览器先发送 OPTIONS 请求,服务端需响应: 携带凭证 (如 Cookie): 前端设置 withCredentials: true ,服务端需指定 Access-Control-Allow-Origin 为具体源(不能为 * ),并返回 Access-Control-Allow-Credentials: true 。 3. 代理服务器 原理 :将跨域请求转发至同源的服务端,由服务端代为请求目标接口。 开发环境:Webpack DevServer 配置 proxy : 生产环境:通过 Nginx 反向代理: 4. postMessage 原理 :允许不同源的窗口间通过消息事件通信。 5. document.domain(适用于子域跨域) 原理 :将同一主域下的子域页面设置为相同域名。 限制:仅适用于 a.example.com 与 b.example.com 之间的跨域。 代码: 三、方案对比与适用场景 | 方案 | 适用场景 | 优势 | 缺陷 | |--------------|-----------------------------|-----------------------------|-------------------------| | JSONP | 老旧浏览器兼容、简单 GET 请求 | 兼容性好 | 安全性低、仅支持 GET | | CORS | 现代浏览器、需灵活控制请求方法 | 前端无需改动、支持多种请求类型 | 需服务端配合 | | 代理服务器 | 开发环境调试、避免服务端改动 | 前端无感知、可缓存请求 | 生产环境需部署代理中间件 | | postMessage | 跨窗口通信(如微前端) | 安全可控、支持复杂数据 | 需主动监听消息事件 | 四、安全注意事项 CORS 的 Access-Control-Allow-Origin: * 需谨慎使用,避免敏感数据泄露。 JSONP 的风险 :可能被恶意注入脚本,需校验数据来源。 代理服务器 需防范 SSRF 攻击(服务端请求伪造)。 通过理解同源策略的约束机制及各类跨域方案的底层原理,可根据实际场景选择最合适的安全解决方案。