在开发过程中,由于使用第三方框架只配置一个代理服务器和后端联调满足不了我们的需求,我们通常会在 vue.config.js或者是vite.config.js 中配置 devServer 来在本地启动一个服务器,在这个选项中,我们会配置proxy 属性来将指向到本地的请求(例如: /api/action) 代理到后端的开发服务器上避免跨域。
//Vue2写法
//栗子
module.exports = definConfig({
devServer: {
proxy: {
"/api": {
target: "http://192.168.1.201:8888", // 目标路径
changeOrigin: true, // 改变请求源
secure: false, // 不使用HTTPS
rewrite: (path) => path.replace(new RegExp("^/api"), ""), // 重写请求路径
},
},
},
});
/*
在上面这个栗子配置中,要注意以下两点:
接口地址有重叠地址时,长度短的放下面 匹配的优先级是从上往下。
*/
/*
列如
### 将 ‘/’ 匹配到路径为 192.168.1.1
### 将 ‘/api’ 匹配到路径为 192.168.1.2
### 将 ‘/api/network’ 192.168.1.3
*/
module.exports = definConfig({
devServer: {
proxy: {
"/": {
target: "192.168.1.1", // 目标路径
changeOrigin: true, // 改变请求源
secure: false, // 不使用HTTPS
rewrite: (path) => path.replace(new RegExp("^/api"), ""), // 重写请求路径
},
"/api": {
target: "192.168.1.2", // 目标路径
changeOrigin: true, // 改变请求源
secure: false, // 不使用HTTPS
rewrite: (path) => path.replace(new RegExp("^/api"), ""), // 重写请求路径
},
"/api/network": {
target: "192.168.1.3", // 目标路径
changeOrigin: true, // 改变请求源
secure: false, // 不使用HTTPS
rewrite: (path) => path.replace(new RegExp("^/api"), ""), // 重写请求路径
},
},
},
});
/*
解释: 上图这种代理的顺序是错误的 现在 /,/api,/api/network 全部都会代理到 192.168.1.1 路径上面去
原因是:这里的匹配实际上是一个正则匹配的过程(正则匹配的过程就是从字符串的左边往右边依次查找,匹配符合的字符串)
当我们请求/api的时候,首先就会读取到配置项的第一个拿配置项的 / 去匹配请求的 /api, 发现请求的/api里面包含 / ,匹配就成功了。
直接就代理到192.168.1.1 路径上面去了。对/api/action的匹配也同理
proxy里面的配置项 又是从上往下一个一个进行匹配 当第一个配置项不符合条件的时候就会拿下一个配置项继续匹配
执行的顺序你可以理解成为下面这种if语句的形式(伪代码 这是只是展示执行的顺序 括号里面的判断条件是不需要管的)
if(/){
target: "192.168.1.1", // 目标路径
}else if(/api){
target: "192.168.1.2", // 目标路径
}else if(/api/network){
target: "192.168.1.3", // 目标路径
}
所以,配置中的地址与请求地址中匹配的字符越少,符合度越低
上例中配置中的地址(/)与请求地址(/api)只有一个字符是匹配的,所以符合度低。
*/
//所以我们正确的写法应该是:
module.exports = definConfig({
devServer: {
proxy: {
"/api/network": {
target: "192.168.1.3", // 目标路径
changeOrigin: true, // 改变请求源
secure: false, // 不使用HTTPS
rewrite: (path) => path.replace(new RegExp("^/api/network"), ""), // 重写请求路径
},
"/api": {
target: "192.168.1.2", // 目标路径
changeOrigin: true, // 改变请求源
secure: false, // 不使用HTTPS
rewrite: (path) => path.replace(new RegExp("^/api"), ""), // 重写请求路径
},
"/": {
target: "192.168.1.1", // 目标路径
changeOrigin: true, // 改变请求源
secure: false, // 不使用HTTPS
rewrite: (path) => path.replace(new RegExp("^/"), ""), // 重写请求路径
},
},
},
});
//Vue3写法(这边就直接展示正确写法了,匹配的原理都是一样的)
export default ({ command, mode }) => {
const config = {
proxy: {
"/api/network": {
target: "192.168.1.3", // 目标路径
changeOrigin: true, // 改变请求源
secure: false, // 不使用HTTPS
rewrite: (path) => path.replace(new RegExp("^/api/network"), ""), // 重写请求路径
},
"/api": {
target: "192.168.1.2", // 目标路径
changeOrigin: true, // 改变请求源
secure: false, // 不使用HTTPS
rewrite: (path) => path.replace(new RegExp("^/api"), ""), // 重写请求路径
},
"/": {
target: "192.168.1.1", // 目标路径
changeOrigin: true, // 改变请求源
secure: false, // 不使用HTTPS
rewrite: (path) => path.replace(new RegExp("^/"), ""), // 重写请求路径
},
},
};
return config;
}
//当然,在正式部署的时候,还是需要后端去做统一代理