易君召
易君召
发布于 2026-07-24 / 2 阅读
0
0

前端跨域问题完整解决方案详解

一、跨域核心原理

浏览器同源策略限制:协议、域名、端口三者任意一个不同,即为跨域,浏览器会拦截响应。

同源三要素:http/httpswww.a.com8080

二、主流解决方案(按使用场景分类)

方案 1:CORS 跨域资源共享(后端标准方案,推荐)

后端通过响应头告知浏览器允许跨域,无前端改造,服务端配置

关键响应头

http

# 允许指定域名,*代表所有域名(生产不推荐)
Access-Control-Allow-Origin: https://xxx.com
# 允许携带Cookie、Token
Access-Control-Allow-Credentials: true
# 允许自定义请求头
Access-Control-Allow-Headers: Content-Type,token
# 允许的请求方法
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
# 预检请求有效期
Access-Control-Max-Age: 3600

不同后端实现示例

  1. SpringBoot Java

java

运行

@CrossOrigin(origins = "https://前端域名", allowCredentials = "true")

全局 CORS 配置类可统一放行。

2. Nginx 反向代理配置 CORS

nginx

add_header Access-Control-Allow-Origin https://xxx.com;
add_header Access-Control-Allow-Credentials true;
  1. Node.js Express

js

运行

app.use(cors({origin:"前端地址",credentials:true}))

预检请求 OPTIONS

复杂请求(带自定义 header、Content-Type 非表单)浏览器先发 OPTIONS 预检,后端必须正常返回 204,否则跨域失败。


方案 2:Nginx 反向代理(前后端分离最常用)

核心思路:同源访问 Nginx,由 Nginx 转发请求到后端,浏览器只和 Nginx 交互,不存在跨域。

适用场景:前端静态资源、后端接口部署在不同服务器。

Nginx 完整配置示例

nginx

server {
    listen 80;
    server_name fe.xxx.com; # 前端访问域名

    # 前端静态资源
    location / {
        root /static/fe;
        index index.html;
    }

    # 所有/api开头接口转发到后端服务
    location /api/ {
        proxy_pass http://127.0.0.1:8090; # 后端真实地址
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

优势:不用改后端代码,统一处理跨域、负载均衡、SSL 证书。


方案 3:JSONP(仅支持 GET 请求,老旧兼容方案,不推荐)

原理:<script>标签不受同源策略限制,通过动态创建 script 标签请求接口,后端返回包裹回调函数的 JS 代码。

前端示例

js

运行

function callback(res) {
  console.log("返回数据", res);
}
// 动态创建script
const script = document.createElement('script');
script.src = 'http://后端域名/api/data?callback=callback';
document.body.appendChild(script);

后端返回格式

js

运行

callback({"code":200,"data":"测试数据"})

缺点:

  1. 仅 GET 请求,无法 POST/PUT

  2. 存在 XSS 安全风险

  3. 不支持携带 Cookie

    现代项目基本淘汰,仅维护老系统时使用。


方案 4:PostMessage(页面间跨域通信:iframe、新开窗口)

适用于:父页面与 iframe 嵌套页面、window.open 新开页面跨域传参。

API:window.postMessage(data, targetOrigin)

示例

  1. 父页面(a.com)发送消息

js

运行

const iframe = document.querySelector('iframe');
iframe.contentWindow.postMessage({type:"getData"}, "https://b.com");
  1. iframe 子页面(b.com)监听

js

运行

window.addEventListener('message', (e) => {
  // e.origin校验来源,防止恶意网站
  if(e.origin !== "https://a.com") return;
  console.log(e.data);
  // 回复数据
  e.source.postMessage({res:"返回内容"}, e.origin);
})

优势:支持复杂数据、双向通信;仅解决页面嵌入场景,不适用接口请求跨域。


方案 5:WebSocket(实时通信无跨域限制)

WebSocket 不受同源策略约束,浏览器不会拦截,适合聊天、推送实时业务。

前端连接:

js

运行

const ws = new WebSocket("ws://后端域名:9000");

注意:WebSocket 握手阶段仍会走 HTTP,如需携带 Cookie,后端仍需配置 CORS。


方案 6:浏览器本地关闭同源策略(仅本地开发调试,严禁生产)

开发时前端本地localhost:5173,后端localhost:8080跨域,临时方案:

Chrome 关闭同源策略

  1. 关闭所有 Chrome 窗口

  2. 终端执行命令:

bash

# Windows
chrome --disable-web-security --user-data-dir="D:\chrome_dev"
# Mac
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-web-security --user-data-dir="/tmp/chrome_dev"

打开后提示「安全模式已禁用」,仅本地调试,存在严重安全风险,生产绝对不能使用。


方案 7:Vite/Webpack 开发代理(前端本地开发专用)

仅作用于本地开发环境,打包上线失效;原理是启动 node 中间件转发请求,规避浏览器跨域。

  1. Vite 配置 vite.config.js

js

运行

export default defineConfig({
  server: {
    proxy: {
      // 匹配/api开头接口
      '/api': {
        target: 'http://127.0.0.1:8090', // 后端地址
        changeOrigin: true, // 修改源,模拟同源
        rewrite: (path) => path.replace(/^\/api/, '') // 去除/api前缀
      }
    }
  }
})
  1. Webpack Vue CLI vue.config.js

js

运行

module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:8090',
        changeOrigin: true,
        pathRewrite: {'^/api': ''}
      }
    }
  }
}

重点:打包部署到服务器后,该代理配置无效,线上仍需要 CORS 或 Nginx 反向代理。

三、方案选型对比表

解决方案

适用场景

请求方法

生产可用

优缺点

CORS

前后端分离、线上生产

全部请求

✅推荐

标准规范,灵活配置;需后端修改

Nginx 反向代理

线上部署、多服务整合

全部请求

✅最优

统一网关,无需改代码;需要运维配置 Nginx

Vite/Webpack 开发代理

本地开发调试

全部请求

❌打包失效

开发便捷,仅本地生效

JSONP

老旧遗留系统兼容

仅 GET

❌不推荐

兼容性差,安全隐患多

PostMessage

iframe 嵌套、多窗口通信

无接口请求,页面传值

仅解决页面通信,不能处理接口跨域

WebSocket

实时推送、聊天业务

双向长连接

无跨域拦截,适合实时场景

关闭浏览器同源策略

临时本地调试

全部请求

❌严禁线上

安全风险极高,仅临时测试

四、常见踩坑点

  1. CORS 中Access-Control-Allow-Origin: *不能搭配Access-Control-Allow-Credentials: true

  2. 自定义 Token 请求头会触发 OPTIONS 预检,后端必须正常响应 OPTIONS;

  3. 开发代理仅本地生效,上线忘记配置 Nginx/CORS 会出现线上跨域;

  4. 携带 Cookie 跨域时,前端请求需要配置withCredentials: true


评论