代理模式通过开发服务器中转请求绕过浏览器同源策略,因浏览器仅检查前端脚本发起的跨域请求,而代理是服务端对服务端通信;vite 中需在 server.proxy 配置路径匹配、target、changeorigin 等选项,并确保 fetch 使用相对路径如 '/api/users'。

直接用 fetch 请求不同源的后端接口,在本地开发时会触发浏览器同源策略拦截。代理模式不是让 fetch 自己“绕过”跨域,而是把请求先发给开发服务器(如 Vite 或 Webpack Dev Server),由它转发到真实后端——此时是服务端对服务端通信,天然不受跨域限制。
为什么代理能绕过跨域
浏览器只对 前端脚本发起的请求 做同源检查,而代理是开发服务器在中间“中转”。比如你本地跑在 http://localhost:5173,后端在 http://localhost:8081,fetch 实际请求的是 /api/users,这个路径被 Vite 拦截,再以服务端身份去调 http://localhost:8081/api/users,响应原样返回给前端。整个过程浏览器只看到同源请求。
Vite 中配置代理的核心步骤
在 vite.config.ts 的 server.proxy 里添加规则:
- 匹配路径前缀,例如
'/api',所有以该前缀开头的 fetch 请求都会被代理 - 设置
target指向真实后端地址,如'http://localhost:8081' - 必须开启
changeOrigin: true,否则后端收到的Origin头仍是localhost:5173,可能校验失败 - 如需去掉前缀再转发(比如前端请求
/api/users,后端实际要/users),加rewrite: (path) => path.replace(/^\/api/, '')
fetch 请求时的关键写法
代理生效的前提是 fetch 不写完整 URL,只写相对路径或带代理前缀的路径:
- ✅ 正确:
fetch('/api/users')或fetch('/api/login')—— 被 Vite 拦截并转发 - ❌ 错误:
fetch('http://localhost:8081/api/users')—— 浏览器直连,必然跨域 - 建议配合环境变量统一管理前缀,比如
fetch(`${import.meta.env.VITE_API_BASE}/users`),开发时设为'/api',生产时设为真实域名
常见问题与应对
代理配好仍报错?重点排查这几项:
- 确认 Vite 服务已重启,代理配置不会热更新
- 检查控制台 Network 面板:请求是否显示为
200且发起地址是localhost:5173(说明走代理);若显示net::ERR_CONNECTION_REFUSED,说明 target 地址不可达 - 后端是否拒绝了带
Origin头的请求?代理虽转发,但默认会带上原始 Origin,可加headers: { Origin: 'http://localhost:8081' }覆盖(慎用,仅调试) - 涉及 Cookie 或认证头时,fetch 需加
credentials: 'include',同时后端Access-Control-Allow-Credentials必须为true,且Access-Control-Allow-Origin不能为*











