跨域问题是由于浏览器的同源策略(Same-Origin Policy)导致的,它限制了不同源(协议、域名、端口任一不同)的资源交互。以下是常见解决方案,按优先级排序:


一、主流解决方案

1. CORS(跨域资源共享) ⭐️ 最推荐
  • 原理:服务端设置响应头声明允许跨域。
  • 实现
    // 服务端响应头示例(以 Node.js 为例)
    Access-Control-Allow-Origin: *       // 允许所有域名(* 生产环境慎用)
    Access-Control-Allow-Origin: https://your-frontend.com // 指定域名
    Access-Control-Allow-Methods: GET,POST,PUT // 允许的请求方法
    Access-Control-Allow-Headers: Content-Type,Authorization // 允许的请求头
    
  • 需预检的请求(如带自定义头或非简单请求):需处理 OPTIONS 预检请求。
2. 代理服务器(Proxy) ⭐️ 前端开发常用
  • 原理:让同源服务器中转请求(浏览器→同源服务器→目标服务器)。
  • 实现
    • 开发环境:用 webpack-dev-server / Vite 代理:
      // vite.config.js
      export default {
        server: {
          proxy: {
            '/api': {
              target: 'http://api.example.com', // 目标服务器
              changeOrigin: true,               // 修改请求头 Host
              rewrite: path => path.replace(/^\/api/, '') // 路径重写
            }
          }
        }
      }
      
    • 生产环境:用 Nginx 反向代理:
      location /api/ {
        proxy_pass http://api.example.com/; # 转发到目标服务器
        add_header Access-Control-Allow-Origin *; # 可选,双重保障
      }
      

二、特殊场景方案

3. JSONP(仅限 GET 请求)
  • 原理:利用 <script> 标签不受同源策略限制的特性。
  • 实现
    <!-- 前端 -->
    <script>
      function handleResponse(data) {
        console.log("收到数据:", data);
      }
    </script>
    <script src="http://api.com/data?callback=handleResponse"></script>
    
    // 服务端返回(需支持 JSONP)
    handleResponse({ "data": "example" });
    
4. WebSocket
  • 原理:WebSocket 协议本身支持跨域。
  • 实现
    const socket = new WebSocket("ws://api.example.com");
    socket.onmessage = event => console.log(event.data);
    
5. 修改 document.domain(仅限子域跨域)
  • 场景a.example.comb.example.com 通信。
  • 实现
    // 在两个页面中均设置
    document.domain = "example.com"; // 降域到同一父域
    

三、其他注意事项

  1. 携带 Cookie 的跨域请求

    • 前端设置:fetch(url, { credentials: 'include' })
    • 服务端需设置:Access-Control-Allow-Credentials: true
      Access-Control-Allow-Origin 不能为 *,必须指定域名。
  2. 避免跨域的替代方案

    • 将前后端部署在同一域名下(如前端 example.com,后端 api.example.com 通过 Nginx 合并域名)。

总结选择

场景 推荐方案
可控的服务端 CORS
前端开发调试 本地代理(webpack/Vite)
生产环境前后端分离 Nginx 代理
仅需 GET 请求的旧系统兼容 JSONP
实时双向通信(如聊天室) WebSocket

优先使用 CORS代理,其他方案作为特殊场景备选。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐