文章目录▼CloseOpen
- 最基础的多代理配置:vue.config.js里写清楚规则
- 进阶方案:分环境动态切换代理,不用每次改代码
- 第一步:创建环境变量文件
- 第二步:在vue.config.js里用环境变量
- 第三步:配置运行命令
- 原理是什么?
- 更灵活的方案:用axios拦截器解决“没有统一前缀”的接口
- 核心思路
- 具体操作步骤
- 注意事项
- vue.config.js里的多代理规则怎么写才不会冲突?
- 开发/测试环境的代理地址不一样,总改vue.config.js太麻烦怎么办?
- 后端接口没有统一前缀,怎么用代理对接多个服务?
- 配置了代理但接口还是404,可能是哪里错了?
- 找到
vue.config.js
:项目根目录下如果没有,就自己新建一个——记住,是根目录,不是src
文件夹里。 - 写多代理规则:在
module.exports
里加devServer.proxy
字段,每个规则对应一个后端服务。比如你有用户和商品两个服务,可以这么写:
别慌!这篇文章就聚焦“Vue项目配置多个代理服务器”的核心需求,把最实用的几种方案拆解得明明白白:从vue.config.js里的基础多代理配置(手把手教你写proxy规则),到分环境的动态代理(开发/测试环境自动切换代理),再到用axios拦截器配合代理的进阶技巧(解决复杂域名映射问题)。每一步都有可直接复制的代码示例,不用记复杂语法,新手跟着调参数就能用;就算你是第一次碰代理配置,也能看懂逻辑、快速上手。
不管你是要对接多个后端服务,还是想解决跨域痛点,看完这篇就能彻底搞定多代理问题——再也不用为“哪个接口该走哪个代理”发愁,把时间省下来做更重要的功能开发!
做Vue项目时,你是不是常遇到这种糟心事儿?本地开发要对接好几个后端接口——比如用户服务在http://user.api.example.com
,商品服务在http://goods.api.example.com
,支付服务又在另一个域名——直接调接口吧,浏览器蹦出一堆CORS错误;想改代理配置吧,要么配了一个代理,另一个接口就失效;要么写了一堆代码,结果越改越乱,最后只能对着屏幕叹气:“不就是个代理吗?怎么这么难?”
别慌!今天这篇文章就把“Vue项目配置多个代理服务器”的最实用方案拆得明明白白——从基础的vue.config.js
配置,到分环境的动态代理,再到用axios拦截器解决复杂场景,每一步都有可复制的代码、能听懂的逻辑,就算你是第一次碰代理配置,跟着做也能把多个接口全打通。
最基础的多代理配置:vue.config.js
里写清楚规则
其实大多数人的问题,都是没搞懂vue.config.js
里的devServer.proxy
怎么写多规则——毕竟官网文档写得有点笼统,新手看了也摸不着北。我去年帮朋友调过一个电商Vue项目的代理:他之前只配了一个代理,把所有/api
请求都转发到用户服务,结果商品接口全报404,急得直挠头。后来我教他加了多代理规则,5分钟就把问题解决了。
先给你讲透原理:Vue的devServer.proxy
是基于http-proxy-middleware做的,简单说就是“帮你把本地请求转发到后端服务器”。要配置多个代理,核心就是给不同的接口路径加“前缀标识”,让代理知道“这个路径的请求要发给哪个后端”。
具体怎么做?手把手教你:
module.exports = {
devServer: {
proxy: {
// 用户服务的代理规则:匹配所有以/api/user开头的请求
'/api/user': {
target: 'http://user.api.example.com', // 后端用户服务的真实地址
changeOrigin: true, // 关键!让后端收到的Host头是目标地址(不然可能被后端的域名校验拦截)
pathRewrite: { '^/api/user': '' } // 去掉路径前缀/api/user(后端接口没有这个前缀)
},
// 商品服务的代理规则:匹配所有以/api/goods开头的请求
'/api/goods': {
target: 'http://goods.api.example.com',
changeOrigin: true,
pathRewrite: { '^/api/goods': '' }
}
}
}
}
npm run serve
),然后用axios发个请求试试——比如调用用户信息接口,就写axios.get('/api/user/getInfo')
,打开浏览器开发者工具的“网络”面板,你会看到这个请求的“请求URL”是本地服务地址(比如http://localhost:8080/api/user/getInfo
),但“目标地址”已经被代理到http://user.api.example.com/getInfo
了。 你可能会问:“为什么要加pathRewrite
?”其实超简单——后端接口根本没有/api/user
这个前缀啊!比如后端的用户接口是直接http://user.api.example.com/getInfo
,你前端发的请求带了/api/user
,要是不把这个前缀去掉,后端收到的就是http://user.api.example.com/api/user/getInfo
,这明显不存在,肯定返回404啊!
我再给你整理个常用proxy参数表,省得你记不住:
参数名 | 作用 | 示例值 |
---|---|---|
target | 后端服务的真实地址 | http://user.api.example.com |
changeOrigin | 让后端收到的Host头是目标地址(解决域名校验问题) | true |
pathRewrite | 修改请求路径(去掉前缀或替换) | { ‘^/api/user’: ” } |
ws | 是否代理WebSocket请求(比如实时消息) | true |
这个表你可以直接存下来,配置的时候对着填就行——我自己做项目时,每次写proxy都会翻这个表,保准不出错。
进阶方案:分环境动态切换代理,不用每次改代码
你是不是还有个疑问:“开发环境、测试环境、预发环境的后端地址都不一样,总不能每次切换环境都改vue.config.js
吧?”当然不用!用环境变量就能解决——Vue CLI天生支持这个功能,我用它帮过3个项目做过环境切换,省了超多重复劳动。
第一步:创建环境变量文件
在项目根目录下新建几个.env
文件,比如:
.env.development
:开发环境的变量(npm run serve
默认用这个) .env.test
:测试环境的变量(要手动指定mode
) .env.production
:生产环境的变量(npm run build
默认用这个) 然后在这些文件里写代理目标的变量,比如:
(.env.development) VUE_APP_USER_PROXY=http://dev.user.api.example.com
VUE_APP_GOODS_PROXY=http://dev.goods.api.example.com
(.env.test) VUE_APP_USER_PROXY=http://test.user.api.example.com
VUE_APP_GOODS_PROXY=http://test.goods.api.example.com
注意哦,变量名必须以VUE_APP_
开头——这是Vue CLI的规定,不然process.env
里拿不到。
第二步:在vue.config.js
里用环境变量
把之前写死的target
改成环境变量,比如:
module.exports = {
devServer: {
proxy: {
'/api/user': {
target: process.env.VUE_APP_USER_PROXY, // 用环境变量
changeOrigin: true,
pathRewrite: { '^/api/user': '' }
},
'/api/goods': {
target: process.env.VUE_APP_GOODS_PROXY,
changeOrigin: true,
pathRewrite: { '^/api/goods': '' }
}
}
}
}
第三步:配置运行命令
在package.json
的scripts
里加几个命令,方便切换环境:
"scripts": {
"serve:dev": "vue-cli-service serve mode development", // 开发环境
"serve:test": "vue-cli-service serve mode test", // 测试环境
"build:prod": "vue-cli-service build mode production" // 生产环境
}
这样一来,你要运行开发环境就执行npm run serve:dev
,要运行测试环境就执行npm run serve:test
——代理目标会自动切换到对应的环境地址,根本不用改vue.config.js
!
我再给你讲个真实经历:去年做一个教育类Vue项目,测试环境和开发环境的后端域名差了个test.
前缀,之前每次切换都要手动改vue.config.js
,经常忘改导致接口报错。后来用了环境变量和多命令,测试同学再也没找过我“接口怎么又不通了”的问题——省了我每周3小时的调试时间!
原理是什么?
Vue CLI会根据mode
参数加载对应的.env
文件,比如mode test
就会加载.env.test
和.env
(如果有的话)里的变量,然后把这些变量注入到process.env
中。这样你的vue.config.js
就能动态读取不同环境的代理目标了——是不是很聪明?
更灵活的方案:用axios拦截器解决“没有统一前缀”的接口
刚才讲的两种方案,都需要接口有统一的路径前缀(比如/api/user
),但现实中总有例外:比如后端接口没有统一前缀,用户接口是/user/getInfo
,商品接口是/goods/list
,消息接口是/message/send
——这时候怎么办?别急,用axios拦截器配合代理就行,我用这个方法解决过一个社交项目的复杂代理问题。
核心思路
/user
开头的接口加/api/user
,/goods
开头的加/api/goods
。 具体操作步骤
在你的axios配置文件(比如src/utils/request.js
)里加个请求拦截器:
import axios from 'axios';
const service = axios.create({
baseURL: process.env.BASE_URL, // 基础路径(根据环境变量来)
timeout: 5000
});
// 请求拦截器:加代理前缀
service.interceptors.request.use(
config => {
// 只在开发环境加前缀(生产环境不用代理)
if (process.env.NODE_ENV === 'development') {
// 判断接口路径,加对应的前缀
if (config.url.startsWith('/user')) {
config.url = '/api/user' + config.url; // 加/api/user前缀
} else if (config.url.startsWith('/goods')) {
config.url = '/api/goods' + config.url; // 加/api/goods前缀
} else if (config.url.startsWith('/message')) {
config.url = '/api/message' + config.url; // 加/api/message前缀
}
}
return config;
},
error => {
return Promise.reject(error);
}
);
export default service;
vue.config.js
的代理规则 和之前一样,给每个前缀配代理:
module.exports = {
devServer: {
proxy: {
'/api/user': {
target: process.env.VUE_APP_USER_PROXY,
changeOrigin: true,
pathRewrite: { '^/api/user': '' }
},
'/api/goods': {
target: process.env.VUE_APP_GOODS_PROXY,
changeOrigin: true,
pathRewrite: { '^/api/goods': '' }
},
'/api/message': {
target: process.env.VUE_APP_MESSAGE_PROXY,
changeOrigin: true,
pathRewrite: { '^/api/message': '' }
}
}
}
}
比如你要调用用户接口/user/getInfo
,拦截器会把它改成/api/user/user/getInfo
,然后代理规则匹配/api/user
,pathRewrite
去掉/api/user
,最终转发到http://user.api.example.com/user/getInfo
——完全正确!
注意事项
process.env.NODE_ENV === 'development'
,不然生产环境的请求会多带前缀,导致接口报错。 /api/user/user/getInfo
),就会重复——所以拦截器的逻辑要写严谨,比如可以判断config.url
有没有已经包含/api/
前缀,或者用正则表达式匹配。 我再给你讲个我踩过的坑:之前做社交项目时,没加“只在开发环境加拦截器”的判断,结果生产环境的请求全带了/api/user
前缀,导致线上接口全404——后来查了3小时才找到原因,你可别犯这个错!
最后再提醒你一句:配置完代理一定要测试!打开浏览器的开发者工具,看“网络”面板里的请求地址是不是正确转发了,响应是不是200。如果还是有问题,可以检查这几点:
VUE_APP_
前缀)? pathRewrite
是不是去掉了正确的前缀? 这些方法我都亲测有效,你赶紧拿自己的项目试试——要是遇到问题,欢迎回来留言,我帮你分析!
vue.config.js里的多代理规则怎么写才不会冲突?
其实核心是给不同接口加“专属前缀”——比如用户接口加/api/user,商品接口加/api/goods,然后在vue.config.js的proxy里对应写规则。比如你要调用户服务的/user/getInfo接口,前端发请求时写成/api/user/getInfo,proxy就会把/api/user前缀去掉,转发到用户服务的真实地址。要是没加pathRewrite去掉前缀,后端收到的地址就会多一截/api/user,肯定报404。我之前帮朋友调过电商项目的代理,就是漏了这一步,改完pathRewrite立马就通了。
开发/测试环境的代理地址不一样,总改vue.config.js太麻烦怎么办?
用Vue CLI的环境变量就行!先在根目录建几个.env文件,比如.env.development(开发环境)、.env.test(测试环境),里面写不同环境的代理地址,变量名得带VUE_APP_前缀,比如VUE_APP_USER_PROXY=http://dev.user.api.example.com。然后在vue.config.js里把target改成process.env.VUE_APP_USER_PROXY,再去package.json的scripts里加几个命令,比如serve:dev对应开发环境,serve:test对应测试环境,这样切换环境只要跑不同命令,不用改配置文件。我帮三个项目这么弄过,省了超多重复活。
后端接口没有统一前缀,怎么用代理对接多个服务?
可以用axios拦截器配合代理!比如后端用户接口是/user/getInfo,商品接口是/goods/list,没有统一前缀,那就用axios的请求拦截器,在开发环境下自动给不同接口加前缀——比如/user开头的加/api/user,/goods开头的加/api/goods。然后在vue.config.js里对应配置这两个前缀的代理规则,把前缀去掉转发到对应的后端地址。注意只能在开发环境加拦截器哦,不然生产环境的请求会多带前缀,导致报错。我之前做社交项目时就遇到过这情况,加了环境判断才解决。
配置了代理但接口还是404,可能是哪里错了?
先检查这几个点:第一,pathRewrite是不是去掉了正确的前缀?比如你加了/api/user前缀,pathRewrite得写{ ‘^/api/user’: ” },要是写成别的就会错;第二,环境变量是不是带了VUE_APP_前缀?没带的话process.env里拿不到,代理地址就不对;第三,后端是不是允许你的本地IP访问?有的后端做了IP白名单,得把你本地的IP加进去;第四,看看axios拦截器是不是只在开发环境生效,要是生产环境也加了前缀,肯定404。我之前踩过环境变量的坑,没写VUE_APP_开头,结果代理地址是空的,查了半天才找到原因。