在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。
什么是代理(proxy)?
代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕过浏览器的跨域限制。
比如前端发起请求:http://localhost:5173/api/user
通过proxy转发代理,最后的实际请求如下:
http://kljshhh.com/api/user
注意:浏览器控制台的请求依旧是http://localhost:5173/api/user,但后端接受的kljshhh.com/api/user
基础语法(Vite & Webpack)
Vite 和 Webpack 中的 proxy 功能都是基于一个第三方库 —— http-proxy-middleware 实现的,这是一个专门用于 Node.js 的 HTTP 代理中间件。
所以,proxy 并不是 Vite/Webpack 原生“自己写的逻辑”,而是封装了这个库来实现开发时的请求转发功能。
http-proxy-middleware 具备:
支持修改请求路径(如 pathRewrite)
支持跨域(changeOrigin)
支持 WebSocket
支持日志、自定义过滤、错误处理等钩子
在vite或webpack中,它的用法基本一致:
Vite 配置(vite.config.js)
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://backend.server.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^/api/, '')
}
}
}
})
Webpack 配置(webpack.config.js)
devServer: {
proxy: {
'/api': {
target: 'http://backend.server.com',
changeOrigin: true,
pathRewrite: { '^/api': '' },
}
}
}
配置项说明
配置项 | 类型 | 含义说明 |
---|---|---|
target | string | 代理目标地址(后端服务器地址) |
changeOrigin | boolean | 是否修改请求头中的 origin字段,设为 true可绕过跨域限制 |
- rewrite(Vite)
pathRewrite(Webpack) | function / object | 用于修改请求路径,如移除 /api前缀 |
| secure | boolean | 默认 true,若代理的是 HTTPS 且使用自签名证书需设为 false |
| ws | boolean | 是否支持 websocket 代理 |
| bypass(Webpack) | function | 返回 false可跳过代理,返回字符串可重定向 |
| headers | object | 发送代理请求时附加的自定义头部 |
| cookieDomainRewrite | `object | string |
使用示例
最基础配置
'/api': {
target: 'http://localhost:3000'
}
请求 /api/user 实际转发到 http://localhost:3000/api/user
去除前缀 /api
Vite:
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: path => path.replace(/^/api/, '')
}
Webpack:
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: { '^/api': '' }
}
请求 /api/user 实际变为 http://localhost:3000/user
多个代理目标
proxy: {
'/api': {
target: 'http://backend1.local',
changeOrigin: true,
rewrite: path => path.replace(/^/api/, '')
},
'/auth': {
target: 'http://auth.local',
changeOrigin: true
}
}
分别将 /api 和 /auth 请求转发到不同的后端服务。
代理 WebSocket
'/ws': {
target: 'ws://localhost:8080',
ws: true
}
支持 WebSocket 通信代理。
实战验证:代理请求原理与匹配分析
正常接口请求地址
http://192.168.4.111:9980/Spring/MVC/entrance/unifier/getReportEnergyQuotaGwByDay
代理配置示例
"/getReportEnergyQuotaGwByDay": {
target: "http://192.168.4.111:9980/",
changeOrigin: true,
}
ajax请求地址:RRequest URLequest URL
/Spring/MVC/entrance/unifier/getReportEnergyQuotaGwByDay
代理后的浏览器Request URL:
原理解析:
根据 proxy 配置中的匹配关键字 /getReportEnergyQuotaGwByDay 拦截请求。
当前页面通过 AJAX 请求地址 /Spring/MVC/entrance/unifier/getReportEnergyQuotaGwByDay,此路径中不包含 /getReportEnergyQuotaGwByDay,因此不会被此配置匹配到,也不会走代理。
实际应该将本地请求路径写为 /getReportEnergyQuotaGwByDay 才能被拦截,然后由代理将其替换成 target 中的真实地址。
注意:proxy 中的 key 是用来匹配请求路径的开头部分,路径不一致将无法触发代理机制。
验证
"/getReportEnergyQuotaGwByDay": {
target: "http://192.168.4.111:9980/Spring/MVC/entrance/unifier/",
changeOrigin: true,
},
AJAX 请求地址:/getReportEnergyQuotaGwByDay
代理后的实际请求地址:
http://192.168.4.111:9980/Spring/MVC/entrance/unifier/getReportEnergyQuotaGwByDay
此时配置生效,因为路径前缀与 proxy 配置匹配成功。
特殊情况:
若请求地址为:getReportEnergyQuotaGwByDay(缺少前导 / )则无法匹配配置 /getReportEnergyQuotaGwByDay,不会走代理。
proxy 匹配是基于字符串开头匹配(精确路径前缀),路径格式必须一致,缺少 / 会导致无法匹配。
作者:快乐就是哈哈哈
链接:https://juejin.cn