在开发环境中,前端项目通常运行在 localhost:3000 等本地服务器上,而API服务可能运行在其他域名或端口,此时浏览器的同源策略会阻止这些请求。使用打包工具的代理功能是最便捷的开发环境跨域解决方案。
一、Vite 代理配置
基本配置(vite.config.js)
export default {
server: {
proxy: {
// 简单字符串写法
'/api': 'http://localhost:4000',
// 详细配置写法
'/api': {
target: 'http://localhost:4000',
changeOrigin: true, // 修改请求头中的host为目标URL
rewrite: path => path.replace(/^/api/, '') // 路径重写
},
// 代理WebSocket
'/socket': {
target: 'ws://localhost:4001',
ws: true
}
}
}
}
实际请求示例
- 前端请求:
fetch('/api/users') - 实际转发:
http://localhost:4000/users
二、Webpack 代理配置
基本配置(webpack.config.js)
module.exports = {
devServer: {
proxy: {
// 简单配置
'/api': 'http://localhost:4000',
// 高级配置
'/api': {
target: 'http://localhost:4000',
changeOrigin: true,
pathRewrite: { '^/api': '' },
// 绕过代理的额外配置
bypass: (req) => {
if (req.url === '/api/noproxy') {
return '/bypass.html';
}
}
}
}
}
}
三、工作原理详解
-
请求拦截:
- 开发服务器根据配置规则拦截匹配的请求
- 不会真实发送到浏览器(避免跨域)
-
请求转发:
- 开发服务器作为中间人向目标服务器发送请求
- 服务器间通信不受同源策略限制
-
响应返回:
- 目标服务器响应被开发服务器接收
- 开发服务器将响应返回给前端
四、高级配置技巧
1. 多环境配置
javascript
复制
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: process.env.API_URL || 'http://localhost:4000',
// ...
}
}
}
}
2. 路径重写规则
proxy: {
'/old-api': {
target: 'http://new-api.com',
rewrite: path => path.replace(/^/old-api/, '/new/path')
}
}
3. 自定义请求头
javascript
复制
proxy: {
'/auth': {
target: 'http://auth-server.com',
headers: {
'X-Custom-Header': 'value'
}
}
}
五、常见问题解决方案
1. 代理不生效检查清单
- 确保配置路径正确(如
/api是否匹配) - 检查开发服务器是否重启
- 确认目标服务器可访问
- 检查是否有拼写错误
2. HTTPS证书问题
javascript
复制
server: {
proxy: {
'/secure': {
target: 'https://example.com',
secure: false // 关闭SSL证书验证
}
}
}
3. 上下文相关代理
proxy: [
{
context: ['/auth', '/api'],
target: 'http://localhost:4000'
}
]
六、与其他工具集成
1. 结合环境变量
javascript
复制
// .env.development
VITE_API_BASE=/api
VITE_API_TARGET=http://localhost:4000
// vite.config.js
proxy: {
[process.env.VITE_API_BASE]: {
target: process.env.VITE_API_TARGET
}
}
2. 与Mock服务配合
proxy: {
'/api': {
target: 'http://localhost:4000',
bypass: (req) => {
// 某些路由使用本地mock数据
if (req.url.includes('/mock')) {
return '/mock/' + req.url.split('/').pop();
}
}
}
}
七、不同场景配置示例
1. 代理到不同路径
proxy: {
'/service': {
target: 'http://backend:8080',
rewrite: path => path.replace(/^/service/, '/api/v2')
}
}
2. 代理多个端点
proxy: {
'/api1': { target: 'http://service1.com' },
'/api2': { target: 'http://service2.com' }
}
3. 条件代理
proxy: {
'/dynamic': {
target: req => {
return req.headers.host.includes('test')
? 'http://test-api.com'
: 'http://prod-api.com';
}
}
}
最佳实践建议
- 统一前缀:所有API请求使用统一前缀(如
/api) - 环境隔离:不同环境使用不同代理目标
- 路径清晰:保持代理路径与实际路径语义一致
- 文档记录:团队内维护代理配置文档
- 安全注意:生产环境务必移除开发代理配置
通过合理配置代理,可以完全模拟生产环境的请求路径,实现开发环境的无缝跨域请求,同时保持代码在不同环境的一致性。