一、前言
在 Vue 项目开发中,我们经常会遇到这样的报错:
Access to XMLHttpRequest at 'http://api.example.com/login'
from origin 'http://localhost:8080' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
这就是典型的 跨域请求被浏览器拦截。
虽然生产环境中通常由后端配置 CORS 或 Nginx 反向代理解决,但在本地开发阶段 ,前后端往往独立运行(前端 localhost:8080,后端 localhost:3000),如何优雅地绕过跨域限制?
本文将带你深入理解跨域原理,并提供 Vue CLI(webpack)和 Vite 两种构建工具下的完整解决方案,让你的开发流程更顺畅。
二、什么是跨域?为什么会出现?
✅ 同源策略(Same-Origin Policy)
浏览器出于安全考虑,实施了"同源策略":只有 协议(protocol)、域名(host)、端口(port) 完全相同,才允许访问彼此的资源。
| 当前页面 | 请求地址 | 是否跨域 | 原因 |
|---|---|---|---|
http://localhost:8080 |
http://localhost:8080/api |
❌ 不跨域 | 同协议、同域名、同端口 |
http://localhost:8080 |
http://localhost:3000/api |
✅ 跨域 | 端口不同 |
http://localhost:8080 |
https://localhost:8080/api |
✅ 跨域 | 协议不同 |
http://localhost:8080 |
http://api.dev.com:8080 |
✅ 跨域 | 域名不同 |
📌 浏览器会阻止 JavaScript 发起跨域请求,除非服务端明确允许(CORS)。
三、开发环境 vs 生产环境的区别
| 环境 | 特点 | 跨域解决方案 |
|---|---|---|
| 开发环境 | 前后端分离,本地启动 | 使用 开发服务器代理(Proxy) |
| 生产环境 | 部署在同一域名下 | 通过 Nginx 反向代理或后端开启 CORS |
📌 重点 :本文聚焦 开发环境 的跨域解决!
四、解决方案 1:Vue CLI / webpack-dev-server 代理(推荐)
如果你使用的是 Vue CLI 创建的项目(基于 webpack),可以通过配置 vue.config.js 实现请求代理。
1. 创建 vue.config.js
在项目根目录创建文件 vue.config.js:
javascript
// vue.config.js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000', // 后端服务地址
changeOrigin: true, // 修改请求头中的 origin
secure: false, // 支持 https 目标
pathRewrite: {
'^/api': '' // 重写路径,去掉 /api 前缀
}
}
}
}
})
2. 前端代码中发起请求
javascript
// 原本请求:http://localhost:3000/user/login
// 现在只需请求:/api/user/login
axios.post('/api/user/login', { username, password })
.then(res => console.log(res.data))
3. 工作原理图解
前端代码 → http://localhost:8080
↓ (浏览器)
axios.post('/api/user/login')
↓
Vue DevServer 拦截以 /api 开头的请求
↓
转发到真实后端 → http://localhost:3000/user/login
↓
返回响应 → 再由 DevServer 返回给前端
✅ 优点:
- 前端无需关心真实后端地址
- 完美绕过浏览器跨域限制
- 配置简单,一行代码搞定
五、解决方案 2:Vite 项目代理(适用于 Vue 3 + Vite)
如果你使用的是 Vite 构建的 Vue 项目(如 create-vue 或 vite create),配置方式略有不同。
1. 修改 vite.config.js
javascript
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '') // Vite 中用 rewrite
}
}
}
})
💡 注意:Vite 中使用
rewrite而不是pathRewrite。
2. 前端请求方式不变
javascript
axios.get('/api/users') // 自动代理到 http://localhost:3000/users
六、进阶配置:多接口前缀代理
如果项目需要对接多个后端服务,可以配置多个代理规则:
javascript
// vue.config.js 或 vite.config.js
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: { '^/api': '' }
},
'/upload': {
target: 'http://upload.service.com',
changeOrigin: true
},
'/mock': {
target: 'https://mockapi.com',
changeOrigin: true,
secure: false
}
}
✅ 示例:
/api/users→http://localhost:3000/users/upload/file→http://upload.service.com/file/mock/data→https://mockapi.com/mock/data
七、其他方案对比(不推荐用于开发)
| 方案 | 是否推荐 | 说明 |
|---|---|---|
| JSONP | ❌ | 仅支持 GET,已被时代淘汰 |
| CORS 后端配置 | ⚠️ 有条件 | 需后端配合,开发期可能无法修改 |
| 浏览器禁用安全策略 | ❌ | 危险操作,影响系统安全 |
| 自己起一个中间 Node 服务 | ⚠️ 复杂 | 小题大做,不如用代理 |
📌 结论 :开发服务器代理是最佳选择!
八、常见问题与解决方案
❌ 问题 1:代理后接口 404?
原因 :pathRewrite 配置错误,路径未正确转发。
解决:
- 检查
target地址是否可达 - 打开浏览器 Network,查看实际请求 URL
- 确保
changeOrigin: true
❌ 问题 2:WebSocket 也能代理吗?
可以!Vite 和 webpack 都支持 WebSocket 代理:
javascript
proxy: {
'/ws': {
target: 'ws://localhost:8080',
ws: true,
changeOrigin: true
}
}
❌ 问题 3:代理后 Cookie/Sessions 丢失?
原因:跨域时 Cookie 默认不携带。
解决:
- 前端请求设置
withCredentials: true
javascript
axios.defaults.withCredentials = true
-
后端响应头需允许:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:8080 # 不能为 *
九、生产环境部署建议
开发期用代理,上线后怎么办?
✅ 推荐方案:Nginx 反向代理
server {
listen 80;
server_name yourdomain.com;
# 前端静态资源
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
# API 代理到后端
location /api/ {
proxy_pass http://backend-server:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
📌 这样前后端共用同一域名,彻底解决跨域问题。
十、总结
| 工具 | 配置文件 | 核心配置 |
|---|---|---|
| Vue CLI (webpack) | vue.config.js |
devServer.proxy |
| Vite | vite.config.js |
server.proxy |
| 生产环境 | Nginx | location + proxy_pass |
✅ 开发环境跨域三步走:
- 确定后端接口地址(如
http://localhost:3000) - 在
vue.config.js或vite.config.js中配置代理 - 前端请求统一加前缀(如
/api)
十一、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!