跨域常用解决方案

先搞清楚一个事实:浏览器根本不关心你代码写得对不对

跨域报错最让人崩溃的地方在于:请求发出去了,服务端也响应了,数据也返回了,但浏览器就是不给你

这不是你的代码有问题,也不是后端接口挂了。浏览器的同源策略在 Fetch 或 XHR 的响应阶段 介入,检查响应头里有没有 Access-Control-Allow-Origin。如果这个头缺失或不匹配,响应体直接丢弃,前端拿到一个空壳

所以跨域的本质是:服务端必须通过响应头告诉浏览器"我允许这个源访问" 。后端不改,前端怎么折腾都没用。

下面按实际开发场景说人话。

CORS:唯一正确的生产级方案

CORS 不是"绕过"跨域,它是 W3C 标准定义的跨域正式通道 。服务端设置响应头,浏览器验证放行。

关键响应头只有几个:

http

yaml 复制代码
Access-Control-Allow-Origin: https://your-frontend.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true

最容易踩的坑在 Preflight(预检请求) 。当你的请求满足以下任一条件时,浏览器会先发一个 OPTIONS 探路请求:

  • 方法不是 GET/HEAD/POST
  • Content-Typeapplication/json(而不是 text/plain
  • 带了自定义请求头(比如 Authorization

这个 OPTIONS 请求不携带你的业务参数,服务端必须返回 204200,并附带上述 CORS 响应头。如果后端只处理了 POST 没处理 OPTIONS,预检就挂了,正式请求根本发不出去

带 Cookie 的场景更严格Access-Control-Allow-Origin 不能是 *,必须写明确的前端域名,同时 Access-Control-Allow-Credentials: true

开发阶段的代理:不是解决跨域,是消灭跨域

CORS 需要后端配合,但开发时后端经常还没部署、或懒得给你配 CORS。代理的本质是:让浏览器以为请求发给了同源的服务,再由开发服务器转发到真正的后端

Vite 代理(当前最主流)

javascript

javascript 复制代码
// vite.config.js
export default {
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3001',
        changeOrigin: true,
        rewrite: path => path.replace(/^/api/, '')
      }
    }
  }
}

前端代码里写 fetch('/api/users'),Vite Dev Server 收到后转发到 localhost:3001/users。浏览器全程只和 localhost:5173 打交道,同源,无跨域

Nginx 反向代理(生产环境标准答案)

开发用 Vite,生产用 Nginx,这是目前最常见的前后端分离部署方式:

nginx

bash 复制代码
location /api/ {
    proxy_pass http://backend-service:3001;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

前端静态文件和 /api 请求都在同一个 Nginx 域名下,浏览器视角全是同源

代理方案的真正价值:不仅消灭了跨域,还隐藏了后端真实地址,顺便解决了 HTTPS 混合内容问题。

命令行禁用 Web 安全:能用,但要知道自己在干什么

有些场景下,你就是不想动后端,也不想配代理。比如临时调一个第三方 API,或者本地调试一个别人的线上页面。

Chrome 的 --disable-web-security 可以直接关掉同源策略。必须配合独立的用户数据目录,否则会和你的日常浏览器配置冲突:

bash

python 复制代码
# macOS
open -n -a "Google Chrome" --args --disable-web-security --user-data-dir=/tmp/chrome_dev

# Windows
"C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir=C:\ChromeDevUserData

启动后地址栏下方会出现黄色警告条"你使用的是不受支持的命令标记",说明配置生效了

这件事的边界很清楚 :只在你自己的机器上,只用于调试。不要把它当成开发流程的一部分,更不要教给团队里不了解原理的人。--user-data-dir 的意义是隔离,别用你的主浏览器配置跑这个模式。

不该再用的方案

JSONP 可以直接划掉了。 它只能发 GET 请求,没有错误处理,有 XSS 风险,唯一的历史价值是让你理解 <script> 标签不受同源限制这件事。2026 年没有任何理由在新项目里用 JSONP。

document.domain 也已经废弃。 之前用于同一主域下子域间通信,现在浏览器逐步移除支持,不要再写进技术方案里。

WebSocket 本身不受同源策略约束 ,但服务端必须自己校验 Origin 头,否则等于把安全责任从浏览器转移给了开发者。如果你用 WebSocket 做实时通信,跨域不是问题,鉴权才是。

选型建议

一张表说清楚:

场景 方案
前后端联调,后端已部署 让后端配 CORS
后端还没好 / 不想打扰后端 Vite/Webpack 代理
生产环境前后端分离 Nginx 反向代理
临时调第三方 API,只想快速验证 Chrome 禁用安全模式
微前端 / iframe 通信 postMessage

核心判断逻辑:能控制后端就上 CORS,不能控制就用代理,都不想动就开一个隔离的调试浏览器。别把临时方案塞进生产代码里。

相关推荐
用户298698530141 小时前
前端如何把 TXT 文本文件转成 Word 文档:React 实践
前端·javascript·react.js
FEF前端团队1 小时前
03# Claude Code实战:终端里的逻辑引擎
前端·ai编程·claude
FEF前端团队1 小时前
04# Codex CLI实战:OpenAI的编程代理
前端·chatgpt·ai编程
掘金挖土1 小时前
前端手摸手跑路之 AI 应用开发(七)
前端·后端
data analyse 4561 小时前
重复事件怎么去重:按请求ID、用户+时间窗还是会话聚合?
前端·数据分析
亿元程序员1 小时前
让Codex直接生成PSD难吗?提示词其实很简单
前端
Moment1 小时前
为什么越来越多开发者开始用 PostgreSQL?
前端·后端·面试
mmsx1 小时前
MapLibre 实战 13|让比例尺显示 100m 而不是 347.2m:屏幕距离换算与两个易错点
android·前端·app
YHL1 小时前
🚀 从 SPA 到 Next.js 全栈:一个大前端的 SEO 突围笔记
前端·后端