vue跨域请求接口代理方式 - 完整解决方案与实战教程
在前后端分离的开发模式下,Vue 项目通常运行在本地开发服务器(如 http://localhost:8080),而后端 API 却部署在另一台服务器或另一个端口上(如 http://api.example.com 或 http://localhost:3000)。此时浏览器会因为同源策略而拦截请求,控制台报出 “Access to XMLHttpRequest at 'xxx' from origin 'xxx' has been blocked by CORS policy” 的错误。更让人头疼的是,很多开发者明明在本地配置了代理,打包上线后却依然 404 或跨域,核心痛点在于混淆了“开发环境代理”与“生产环境代理”的边界,以及没有理解 Vue CLI / Vite 代理配置中 rewrite 与 pathRewrite 的差异。本文将从实际排坑角度出发,带你彻底搞懂 Vue 跨域请求接口代理的几种方式。
问题现象
典型报错信息如下,通常出现在浏览器控制台 Network 面板中:
- 请求地址显示为
http://localhost:8080/api/user,但返回 404 或 502。 - 控制台提示
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource。 - 使用 axios 直接请求后端真实域名时,浏览器预检请求(OPTIONS)失败。
- 本地开发正常,
npm run build部署后接口全部失效。
原因分析
浏览器同源策略要求协议、域名、端口三者完全一致。Vue 开发服务器默认启动在 localhost:8080,而后端接口若在 localhost:3000,端口不同即构成跨域。解决方式有两种:后端开启 CORS,或前端使用代理服务器转发请求。代理的本质是让浏览器请求同源的开发服务器,再由开发服务器(Node.js 层)转发到真实后端,从而绕过浏览器限制。但很多开发者误以为代理配置能带到生产环境,实际上 Vue CLI 和 Vite 的 devServer.proxy 只在开发阶段生效,生产环境必须依赖 Nginx 或后端 CORS。
解决方案(附完整代码)
下面分别给出 Vue CLI(webpack)和 Vite 两种主流脚手架的代理配置方式,并附带完整注释。
方案一:Vue CLI 项目(vue.config.js)
在项目根目录创建或修改 vue.config.js:
// vue.config.js
module.exports = {
devServer: {
// 开发服务器端口,默认 8080
port: 8080,
proxy: {
// 匹配所有以 /api 开头的请求路径
'/api': {
// 目标后端地址,注意不要加 /api 后缀
target: 'http://localhost:3000',
// 允许跨域,本质是修改请求头中的 Origin
changeOrigin: true,
// 是否启用 websocket 代理,一般 false
ws: false,
// 路径重写:把 /api 前缀去掉再转发给后端
// 例如 /api/user -> http://localhost:3000/user
pathRewrite: {
'^/api': ''
}
}
}
}
}
前端请求时统一使用相对路径:
// axios 实例配置
import axios from 'axios'
const request = axios.create({
// 这里写 /api,开发环境会被代理拦截并转发
baseURL: '/api',
timeout: 5000
})
export default request
方案二:Vite 项目(vite.config.js)
Vite 的代理配置位于 server.proxy,语法与 http-proxy 一致,但注意 Vite 没有 pathRewrite,而是使用 rewrite:
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
port: 5173,
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
// Vite 中使用 rewrite 而不是 pathRewrite
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
})
方案三:生产环境 Nginx 反向代理(必备)
开发代理不能用于生产,打包后需要 Nginx 转发:
# nginx.conf 片段
server {
listen 80;
server_name your-domain.com;
# 前端静态资源
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
# 接口代理
location /api/ {
# 后端真实地址,注意末尾斜杠
proxy_pass http://backend-server:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
排查步骤与避坑清单
- 确认代理是否生效:修改配置后必须重启开发服务器,热更新不会重新加载 proxy 配置。
- 检查 baseURL 与代理前缀是否一致:如果 axios 的 baseURL 是
/api,则 proxy 的 key 也必须是/api,否则无法匹配。 - 区分 pathRewrite 与 rewrite:Vue CLI 用
pathRewrite,Vite 用rewrite,写错不会报错但代理不生效。 - target 末尾不要带斜杠:写成
http://localhost:3000/可能导致路径拼接异常,推荐不带斜杠。 - 生产环境不要依赖 devServer:打包后
vue.config.js中的 proxy 完全失效,必须配置 Nginx 或让后端开启 CORS。 - 检查后端是否监听 0.0.0.0:如果后端只监听
127.0.0.1,代理转发可能被拒绝。 - 使用 curl 验证:在终端执行
curl http://localhost:8080/api/user,若返回后端数据则代理成功。
掌握以上三种方式,你就能在开发阶段用代理优雅解决跨域,在生产环境用 Nginx 稳定转发,彻底告别 CORS 报错。