# Vite 代理配置指南 ## 概述 本项目使用 Vite 的代理功能来解决开发环境的跨域问题。 ## 代理配置 ### 配置文件 代理配置在 `vite.config.ts` 中: ```typescript server: { proxy: { // 代理所有 /api 开头的请求 "/api": { target: "http://localhost:8080", changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ""), }, // 代理系统接口 "/sys": { target: "http://localhost:8080", changeOrigin: true, }, // 代理 WebSocket "/websocket": { target: "http://localhost:8080", changeOrigin: true, ws: true, }, }, } ``` ## 工作原理 ### 开发环境 在开发环境中(`npm run dev`): 1. 前端运行在 `http://localhost:3000` 2. 后端运行在 `http://localhost:8080` 3. 所有以 `/api`、`/sys` 开头的请求会被代理到后端 **请求流程:** ``` 浏览器请求: http://localhost:3000/sys/user/list ↓ Vite 代理: http://localhost:8080/sys/user/list ↓ 后端响应 ``` ### 生产环境 在生产环境中(`npm run build`): 1. 前端打包后部署到服务器 2. 使用完整的 API 地址(从环境变量读取) 3. 不经过代理,直接请求后端 **请求流程:** ``` 浏览器请求: https://api.example.com/sys/user/list ↓ 后端响应 ``` ## 环境变量配置 ### 开发环境 (`.env.development`) ```bash # 开发环境使用本地后端 VITE_API_BASE_URL=http://localhost:8080 ``` ### 生产环境 (`.env.production`) ```bash # 生产环境使用实际后端地址 VITE_API_BASE_URL=https://api.example.com ``` ## 代理规则说明 ### 1. `/api` 路径代理 ```typescript "/api": { target: "http://localhost:8080", changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ""), } ``` **作用:** 将 `/api` 前缀去掉后转发 **示例:** - 请求:`/api/users/list` - 转发:`http://localhost:8080/users/list` ### 2. `/sys` 路径代理 ```typescript "/sys": { target: "http://localhost:8080", changeOrigin: true, } ``` **作用:** 保留 `/sys` 前缀转发 **示例:** - 请求:`/sys/user/list` - 转发:`http://localhost:8080/sys/user/list` ### 3. WebSocket 代理 ```typescript "/websocket": { target: "http://localhost:8080", changeOrigin: true, ws: true, } ``` **作用:** 代理 WebSocket 连接 ## 常见问题 ### 1. 代理不生效 **原因:** 请求路径不匹配代理规则 **解决:** 确保请求路径以配置的前缀开头(如 `/api`、`/sys`) ```typescript // ✅ 正确 - 会被代理 http.get("/sys/user/list"); // ❌ 错误 - 不会被代理 http.get("http://localhost:8080/sys/user/list"); ``` ### 2. 跨域问题 **原因:** `changeOrigin` 未设置为 `true` **解决:** 确保代理配置中有 `changeOrigin: true` ```typescript "/api": { target: "http://localhost:8080", changeOrigin: true, // 必须设置 } ``` ### 3. Cookie 无法携带 **原因:** 跨域请求默认不携带 Cookie **解决:** 在代理配置中添加 Cookie 相关配置 ```typescript "/api": { target: "http://localhost:8080", changeOrigin: true, cookieDomainRewrite: "localhost", } ``` ### 4. HTTPS 证书问题 **原因:** 后端使用自签名证书 **解决:** 添加 `secure: false` ```typescript "/api": { target: "https://localhost:8443", changeOrigin: true, secure: false, // 忽略证书验证 } ``` ## 高级配置 ### 1. 多个后端服务代理 ```typescript server: { proxy: { // 用户服务 "/api/user": { target: "http://localhost:8081", changeOrigin: true, }, // 订单服务 "/api/order": { target: "http://localhost:8082", changeOrigin: true, }, }, } ``` ### 2. 根据环境变量动态配置 ```typescript import { loadEnv } from "vite"; export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), ""); return { server: { proxy: { "/api": { target: env.VITE_API_BASE_URL, changeOrigin: true, }, }, }, }; }); ``` ### 3. 请求日志 ```typescript "/api": { target: "http://localhost:8080", changeOrigin: true, configure: (proxy, options) => { proxy.on("proxyReq", (proxyReq, req, res) => { console.log("代理请求:", req.method, req.url); }); proxy.on("proxyRes", (proxyRes, req, res) => { console.log("代理响应:", proxyRes.statusCode, req.url); }); }, } ``` ### 4. 请求重写 ```typescript "/api": { target: "http://localhost:8080", changeOrigin: true, rewrite: (path) => { // 移除 /api 前缀 const newPath = path.replace(/^\/api/, ""); console.log(`重写路径: ${path} -> ${newPath}`); return newPath; }, } ``` ## 部署注意事项 ### 1. Nginx 反向代理 生产环境通常使用 Nginx 做反向代理: ```nginx server { listen 80; server_name example.com; # 前端静态资源 location / { root /var/www/html; try_files $uri $uri/ /index.html; } # 后端 API 代理 location /api { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /sys { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } ``` ### 2. 前后端分离部署 如果前后端部署在不同域名: **前端:** `https://www.example.com` **后端:** `https://api.example.com` 需要在 `.env.production` 中配置完整的后端地址: ```bash VITE_API_BASE_URL=https://api.example.com ``` 同时后端需要配置 CORS: ```java @Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("https://www.example.com"); config.addAllowedMethod("*"); config.addAllowedHeader("*"); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } } ``` ## 调试技巧 ### 1. 查看代理日志 在 `vite.config.ts` 中添加日志: ```typescript server: { proxy: { "/api": { target: "http://localhost:8080", changeOrigin: true, configure: (proxy) => { proxy.on("error", (err) => { console.log("代理错误:", err); }); proxy.on("proxyReq", (proxyReq, req) => { console.log("发送请求:", req.method, req.url); }); proxy.on("proxyRes", (proxyRes, req) => { console.log("收到响应:", proxyRes.statusCode, req.url); }); }, }, }, } ``` ### 2. 使用浏览器开发者工具 1. 打开 Network 面板 2. 查看请求的 URL 3. 检查请求头和响应头 4. 确认是否被代理 ### 3. 测试代理配置 ```bash # 启动开发服务器 pnpm dev # 在浏览器中访问 http://localhost:3000 # 在控制台测试请求 fetch('/sys/user/list').then(r => r.json()).then(console.log) ``` ## 参考资料 - [Vite 官方文档 - server.proxy](https://vitejs.dev/config/server-options.html#server-proxy) - [http-proxy-middleware 文档](https://github.com/chimurai/http-proxy-middleware)