简单记录:devServer的proxy和axios的baseURL相关
最近做着做着项目,vue项目需要搞几个不同的url来代理跨域,有点搞不清楚vue.config.js里面的devServer的proxy和axios的baseURL的那些东西了,先简单记录一下:
axios的base_url填什么好?
具体而言就是:是111.xxx.xxx.xxx:8888
这样的ip:port
模式呢?还是直接写/api
这样呢?
很简单:如果写成ip:port模式的话,就是axois直接发出去了,而写上api,再配上proxy字段就实现了代理的作用。
例如:本机开发模式跑在:localhost:8080
,发出post请求:/api/login
,然后proxy填的是:
'/api': {
target: `111.xxx.xxx.xxx:8888`
}
那么此时直接axois的baseURL填你要代理的url:111.xxx.xxx.xxx:8888
的话,请求会不经过proxy的代理了,这个post请求直接的就发出去了....如果后台做了Access-Control-Allow-Origin: *`的话那还算幸运,否则就跨域请求被浏览器拦截了
而如果是baseURL采用的是/api
的方式的话,就直接匹配到了proxy,就会被代理到target指向的url
代理指的是什么?
正好自己遇到过一次自己express写的后台进行了一下代理的经过(不过也不知道是不是正解):
// get:访问 http://localhost:8081/queryText
router.get('/queryText', (req, res) => {
var postData = {
// info here...
};
var options = {
url: 'https://111.xxx.xxx.xxx:8888',
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=UTF-8'
},
json: postData
};
// 引用的request库
request(
options,
(error, response, body) => {
let txt ="";
if(body.error_code ===0) {
txt = body;
res.send(txt);
}
if(txt === "") {
res.send("xxx");
}
}
);
});
也就是前端请求后台的url:http://localhost:8081/queryText
的时候,后台把前台传过来的数据再进行一次postData
的封装,然后再调用了一下request
库把这个请求转发出去,这样就实现了代理的作用...
为什么后台可以,而前端不可以?,就是因为此时后台充当的是HTTP CLIENT,而前端的跨域是由于浏览器的同源策略导致的被浏览器拦截下来了...
为什么proxy里面的需要代理的字段有时需要^符号?
这部分之前也有些不懂,但没遇到过什么问题,一直没去想过,之后,遇到了写^/api
的情况,但是自己的测试表示,写/api
也一样...
一个简单的测试:
写/dev/api
,在原来的post接口情况下,加了一个前缀,这样其余不改的情况下,就报错了,因为请求的requestURL是:xxx/dev/api
,而不是之前的xxx/api
第一次以为^表示和*号大致差不多,就是包括前面的所有的然后只有出现了api才就开始代理,于是proxy改成^/api/
,觉得在发post请求,url就会被代理成:111.xxx.xxx.xxx:8888/dev/api
,这样也的确还是会报错,于是再加上一个pathRewrite字段:
pathRewrite: {
'^/dev': ''
}
把dev给替换掉,但是还是报错....,这就充分说明了^表示和*号大致差不多,这个思路完全是错的...,而且之后还是变成原来的/api
,pathRewrite字段保留,结果却成功了...
正好,网上搜了一下,^符号,如果大致没猜错的话,这个原来只是正则,表示以什么什么开头,这也成功解释了,为什么变成原来的/api
,pathRewrite字段保留,结果却成功了。
参考:
为什么需要pathRewrite?
经过以上应该知道了pathRewrite字段,就是用来替换url中的某些字符串,保证代理之后的url是正确的作用,
这样需要考一下:如果axios的baseURL写的是/api
,但proxy里面的target却是:111.xxx.xxx.xxx:8888/api
的时候会出现什么情况呢?404
从发出的请求,到被proxy之后的请求,再到实际发出的请求,三个部分来考虑:
- 发出的请求:仍然是之前的:
localhost:8080/api/login
- 被proxy之后的请求:
111.xxx.xxx.xxx:8888/api/api/login
- 实际发出的请求:
111.xxx.xxx.xxx:8888/api/api/login
这样问题就找到了,因为proxy只是提示遇到了/api就是需要代理了,但是它并不会去做把清理,替换的工作,也就是target里面的那个api被保存了,同时,axios的post的/api/login也保存了,此时就需要pathRewrite来做了:
pathRewrite: {
'^/api': ''
}
这样就会去掉那个多余的api字符串了,我觉得整个过程最主要的是要注意到这个转化的过程,而之前觉得有点不懂的原因,也是因为没有直观的体会到这个转化的过程
其实在官方文档里有一个字段:logLevel,如果添加上了logLevel: 'debug'
,这样的话就会把每次请求的代理过程在命令行中输出出来,很清晰了!
临时性的总结,可能还有一些理解错误和疏漏,谅解