开发环境跨域解决方案(Vite/Webpack代理配置)

322 阅读3分钟

在开发环境中,前端项目通常运行在 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. 请求拦截

    • 开发服务器根据配置规则拦截匹配的请求
    • 不会真实发送到浏览器(避免跨域)
  2. 请求转发

    • 开发服务器作为中间人向目标服务器发送请求
    • 服务器间通信不受同源策略限制
  3. 响应返回

    • 目标服务器响应被开发服务器接收
    • 开发服务器将响应返回给前端

四、高级配置技巧

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';
    }
  }
}

最佳实践建议

  1. 统一前缀:所有API请求使用统一前缀(如/api
  2. 环境隔离:不同环境使用不同代理目标
  3. 路径清晰:保持代理路径与实际路径语义一致
  4. 文档记录:团队内维护代理配置文档
  5. 安全注意:生产环境务必移除开发代理配置

通过合理配置代理,可以完全模拟生产环境的请求路径,实现开发环境的无缝跨域请求,同时保持代码在不同环境的一致性。