最近做着做着项目,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字段保留,结果却成功了。

参考:

http-proxy-middleware#options

micromatch

glob

为什么需要pathRewrite?

经过以上应该知道了pathRewrite字段,就是用来替换url中的某些字符串,保证代理之后的url是正确的作用,

这样需要考一下:如果axios的baseURL写的是/api,但proxy里面的target却是:111.xxx.xxx.xxx:8888/api的时候会出现什么情况呢?404

从发出的请求,到被proxy之后的请求,再到实际发出的请求,三个部分来考虑:

  1. 发出的请求:仍然是之前的:localhost:8080/api/login
  2. 被proxy之后的请求:111.xxx.xxx.xxx:8888/api/api/login
  3. 实际发出的请求:111.xxx.xxx.xxx:8888/api/api/login

这样问题就找到了,因为proxy只是提示遇到了/api就是需要代理了,但是它并不会去做把清理,替换的工作,也就是target里面的那个api被保存了,同时,axios的post的/api/login也保存了,此时就需要pathRewrite来做了:

pathRewrite: {
  '^/api': ''
}

这样就会去掉那个多余的api字符串了,我觉得整个过程最主要的是要注意到这个转化的过程,而之前觉得有点不懂的原因,也是因为没有直观的体会到这个转化的过程

其实在官方文档里有一个字段:logLevel,如果添加上了logLevel: 'debug',这样的话就会把每次请求的代理过程在命令行中输出出来,很清晰了!

临时性的总结,可能还有一些理解错误和疏漏,谅解

标签: none

添加新评论