在 Vue + Vite 的项目中,利用代理服务解决跨域问题是开发环境中最常用的方案。
一、代理服务的原理
代理服务解决跨域问题的核心思想是:"欺骗"浏览器的同源策略。
- 同源策略 是浏览器施加的限制:浏览器发起的跨域请求会被拦截。
- 但服务器之间的通信没有这个限制------后端服务器可以自由地向任何其他服务器发送 HTTP 请求。
代理服务的工作原理如下:
- 前端应用(Vue 开发服务器,例如
http://localhost:5173)在本地启动了一个开发服务器(Vite Dev Server)。 - 当前端需要请求后端 API(例如
http://api.example.com/data)时,并不直接向目标后端发送请求,而是向同源 的开发服务器发送请求,例如http://localhost:5173/api/data。 - 开发服务器收到这个请求后,作为中间人 ,将请求转发给真正的目标服务器
http://api.example.com/data。 - 目标服务器返回数据给开发服务器,开发服务器再将数据返回给前端。
关键点 :浏览器始终认为它在与同源的 http://localhost:5173 通信,因此不会触发跨域拦截。而开发服务器与目标服务器之间的通信是后端到后端,不受同源策略限制。
二、Vite 中配置代理的具体方法
Vite 的开发服务器内置了代理功能,通过 vite.config.js 中的 server.proxy 选项即可配置。
步骤 1:创建或打开 vite.config.js
确保项目根目录下存在 vite.config.js 文件(如果是 TypeScript 项目,可能是 vite.config.ts)。
步骤 2:配置 server.proxy
下面是一个常见的配置示例:
javascript
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
// 选项写法:将 '/api' 开头的请求代理到 target
'/api': {
target: 'http://api.example.com', // 目标后端地址
changeOrigin: true, // 必须设置为 true,以便虚拟主机站点能正确获取请求来源
rewrite: (path) => path.replace(/^\/api/, ''), // 可选,重写路径,去掉 '/api' 前缀
// secure: false, // 如果目标地址是 HTTPS 但证书无效,可以设置为 false 允许继续
},
// 简单的字符串写法:将所有 '/foo' 请求代理到 target/foo
// '/foo': 'http://localhost:4567',
},
},
})
常用配置项说明
target:代理的目标服务器地址(协议 + 域名 + 端口)。changeOrigin:建议设置为true。因为后端可能根据请求头中的Origin字段判断来源,设置为true可以覆盖为target的域名,避免被后端拒绝。rewrite:用于重写请求路径。例如前端请求/api/users,如果后端接口实际路径是/users,就可以用rewrite将/api前缀去掉。secure:当代理到 HTTPS 地址且目标服务器的 SSL 证书无效时(如自签名证书),可以设为false允许继续转发。生产环境不建议这样做。
步骤 3:在 Vue 组件中使用代理后的地址
配置完成后,在代码中请求 /api 开头的路径即可:
javascript
// 例如请求 http://localhost:5173/api/users
// 会被代理到 http://api.example.com/users
fetch('/api/users')
.then(res => res.json())
.then(data => console.log(data))
如果后端接口本来就没有 /api 前缀,记得使用 rewrite 函数将它去掉。
步骤 4:启动开发服务器
bash
npm run dev
# 或 yarn dev
此时所有匹配的请求都会被自动代理。
三、注意事项
- 仅限开发环境 :Vite 的代理功能仅在开发服务器中生效,打包后(
build)不再存在。生产环境的跨域问题仍需后端配置 CORS 或使用 Nginx 等反向代理。 - 多个代理规则:可以配置多个代理,Vite 会按顺序匹配。
- Cookie 与认证 :如果后端需要 Cookie 或认证头,代理默认会转发这些信息,因为浏览器将请求发给了同源开发服务器,Cookie 也会携带(前提是开发服务器的 Cookie 与后端一致,这通常不适用)。如果需要携带后端 Cookie,最好还是在后端配置 CORS +
withCredentials方案。 - 路径重写注意 :
rewrite使用正则或字符串替换,确保不要误删必要路径。 - WebSocket 代理 :Vite 也支持 WebSocket 代理,配置方式类似(需要额外设置
ws: true)。
四、示例:完整的配置
假设后端 API 地址为 https://api.myapp.com/v1,且前端希望使用 /api 前缀访问:
javascript
// vite.config.js
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
'/api': {
target: 'https://api.myapp.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '/v1'), // 将 /api 替换为 /v1
// 如果目标接口直接就是 /api 开头的,可以不用 rewrite
},
},
},
})
前端请求:
javascript
axios.get('/api/users') // 实际请求 https://api.myapp.com/v1/users