一、常规跨域配置

假如我有一个请求跨域了,请求url为:http://172.21.34.65:8090/kweb/temp/testCros,现在我要代理它。则常规配置如下:

module.exports = {
    devServer: {
        port: 8888, //前端服务启动的端口号
        host: 'localhost', //前端服务启动后的访问ip,默认为localhost, host和port组成了前端服务启动后的访问入口。
        https: false,
        open: true,
        proxy: {
            '/kweb': { //拦截上下文
                target: 'http://172.21.34.65:8090', //匹配到要代理的上下文后,将上下文前面的地址替换为此代理地址
                changeOrigin: true, //是否跨域
                pathRewrite: {
                    '^/':'' //拦截到的上下文重写,这里可以将 kweb 重写为空或者其它值,因为我不需要重写,所以这里这么配置。
                }
            }
        }
    }
}

请留意host、port的注释说明,这两个参数配置了前端服务的访问入口。

二、跨域不生效探究

跨域产生的根源归根结底是浏览器的同源策略(所以我们用postman或者通过后端代码调用服务不会遇到跨域问题),至于什么是同源策略这里不过多介绍,感兴趣的可以搜索细看。这里直接讲解跨域的解决方式,及其本人遇到的不生效原因探查。

首先vue中跨域问题是通过代理(请求转发)解决,代理的本质是创建一个代理对象,代理当前前端服务的请求,将该请求转发给指定的服务端,再将服务端返回的结果转发给前端。所以能代理的请求必须和当前前端服务保持一致。即要代理的请求url,其对应的ip和port必须与devServer中的host port保持一致。 

为什么呢?

跨域配置中的host port,是前端服务启动后的访问地址,因为我们通常是在本地启动,所以host一般不需要配置,默认是localhost ,不过也可以配置成0.0.0.0,这样同一网段的所有主机都可以访问了,port是前端服务启动后的访问端口,默认是8080,存在端口冲突时可以通过配置该参数进行解决。前端中的所有请求,只要使用的是该host port,那么就会被该配置拦截,如果我们配置了代理,那么就会进一步匹配上下文,如果上下文匹配上了,则可以进行请求的代理发送。

到这里基本可以猜出来为什么代理不生效了吧!

即axios发送请求时,如果url中不包含ip port,那么默认会用前端服务的host port作为其ip port,此时这个url一定会被代理拦截,然后再进一步匹配上下文,如果匹配则进行代理的转发。如果axios url中的ip port和配置的host port不同,那么就不会进入代理拦截,更不会进入上下文的匹配和跨域代理转发

三、总结(建议)

通过以上分析,推荐再axios请求发送时不要添加ip port,而是再代理转发时通过target参数配置,因为我们如果在axios请求中不添加ip port,那么前端服务会使用默认的host port,那么它一定会进入代理配置中,此时只要上下文匹配上,就会进行代理转发。

如果需要代理不同服务器的请求也不用担心,因为在代理配置中我们可以配置多个上下文拦截,进而代理不同服务器的服务请求

上面这些信息是我通过查资料和本人试验验证出来的,并没有从源码角度追踪验证其正确性,如果有不对的地方,欢迎指正。


 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐