Skip to content

浏览器跨域解决方案

浏览器跨域问题源于同源策略(Same-Origin Policy),它是浏览器重要的安全机制,限制不同源的文档或脚本进行交互。解决跨域的常用方案如下:


1. CORS (跨域资源共享)

原理:服务端设置响应头,告诉浏览器允许特定来源的请求访问资源。
适用场景:主流且安全的跨域解决方案,需服务端配合。 实现方式

http
Access-Control-Allow-Origin: https://yourdomain.com  # 允许特定域名
Access-Control-Allow-Origin: *                      # 允许所有域名(慎用)
Access-Control-Allow-Methods: GET, POST, PUT        # 允许的请求方法
Access-Control-Allow-Headers: Content-Type, Authorization  # 允许的请求头
  • 预检请求(Preflight):复杂请求(如带自定义头)会先发 OPTIONS 请求,服务端需响应预检头。
  • 携带凭证:若请求需传递 Cookie,需设置:
    javascript
    // 前端
    fetch(url, { credentials: 'include' })
    http
    // 服务端
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Origin: https://yourdomain.com  # 不能为 *

2. JSONP (JSON with Padding)

原理:利用 <script> 标签不受同源策略限制的特性,动态创建脚本获取数据。
适用场景:仅支持 GET 请求,老式浏览器兼容方案。 实现方式

javascript
// 前端
function handleResponse(data) {
  console.log(data);
}
const script = document.createElement('script');
script.src = 'https://api.com/data?callback=handleResponse';
document.body.appendChild(script);

// 服务端返回
handleResponse({ "data": "value" });

缺点:安全性低(易受 XSS 攻击),错误处理困难。


3. WebSocket

原理ws://wss:// 协议不受同源策略限制。
适用场景:实时双向通信(如聊天室)。 实现方式

javascript
const socket = new WebSocket('wss://api.com');
socket.onmessage = (event) => {
  console.log(event.data);
};

4. 代理服务器

原理:让同源服务器转发跨域请求(浏览器 → 同源代理 → 目标服务器)。
适用场景:无法修改目标服务器时(如第三方 API)。 实现方式

  • 开发环境:使用 webpack-dev-server、Vite 代理:
    javascript
    // vite.config.js
    export default {
      server: {
        proxy: {
          '/api': {
            target: 'https://api.com',
            changeOrigin: true,
          }
        }
      }
    }
  • 生产环境:通过 Nginx 配置反向代理:
    nginx
    location /api/ {
        proxy_pass https://api.com/;
        proxy_set_header Host $host;
    }

5. postMessage API

原理:允许不同源的窗口间安全通信(如 iframe 与父页面)。
适用场景:跨窗口/跨 Tab 通信。 实现方式

javascript
// 发送方(iframe 内部)
parent.postMessage('Hello', 'https://parent-domain.com');

// 接收方(父页面)
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://iframe-domain.com') return;
  console.log(event.data); // 'Hello'
});

6. 修改 document.domain

原理:强制让两个页面拥有相同的基础域名(如 a.example.comb.example.com 都设为 example.com)。
适用场景:仅限主域相同、子域不同的情况。 实现方式

javascript
// 两个页面都设置
document.domain = 'example.com';

注意:现代浏览器已逐渐弃用此方案。


7. CORS 代理服务(第三方)

原理:使用公共代理服务(如 cors-anywhere)中转请求。
适用场景:临时测试或无法自建代理时。 示例

javascript
fetch('https://cors-anywhere.herokuapp.com/https://api.com/data')

总结对比

方案适用场景是否需要服务端配合安全性请求类型
CORS主流跨域方案⭐⭐⭐⭐⭐所有 HTTP 方法
JSONP兼容老旧系统是(需支持回调)⭐⭐仅 GET
代理服务器无法修改目标服务器时否(自建代理)⭐⭐⭐⭐所有方法
WebSocket实时双向通信⭐⭐⭐⭐双向通信
postMessage跨窗口通信⭐⭐⭐⭐自定义消息

关键建议

  • 优先使用 CORS(安全且标准化)。
  • 开发环境用 代理 避免跨域问题。
  • 避免使用 * 开放 CORS,应明确指定可信域名。
  • 敏感操作(如 Cookie)务必设置 Access-Control-Allow-Credentials: true 并限制来源域名。

根据实际场景选择合适的方案,可高效解决跨域问题并保障安全性。