完美级解决web开发跨域问题
- 2020 年 4 月 3 日
- 筆記
背景
1、什么是跨域
依据我的理解,出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求, 如果你尝试突破这个限制,就是跨域。那么什么情况下会触发跨域呢?
1、域名不同,很显然了。
2、端口不同,嘿嘿,踩坑了吧
3、协议不同,你http,人家https,嘿嘿,又踩坑了吧。
学完了,那我问个问题,你别哭哈..
1、a.test.com,异步访问test.com 算跨域吗? 2、test.com异步访问a.test.com 算跨域吗?
2、为什么要解决跨域
因为,我们在开发的时候,开发过程中的代码是在本地的,一般来说,只是起一个
localhost:8080
的本地server而已,假如你访问 test.qq.com,很明显,跨域了吧,拿不到接口数据的你一筹莫展,所以,怎么办呢?
解决跨域
这里想直接说下在vue项目中怎么解决跨域访问线上环境接口的问题。
1、跪舔模式
让后台大佬支持:
可以想象一下挺麻烦的,毕竟依赖人家嘛,不推荐。
2、jsonp
我都懒得提这种方式,但不适合我们,因为我们上线后的代码并不跨域,只是本地跨域而已,扯这个方案一般来说是为了解决我们访问别人的网站接口。
3、代理
代理的方式是在是太多了,比如nginx代理,基于node编写的whistle这个代理,等等等等,其原理无非就是给你制造不跨域的访问而已。见下图所示
比如,本来我要访问test.qq.com/api1,因为有代理的存在,我访问localhost:8080/api1,然后,让代理去访问test.qq.com/api1即可,请注意了,代理是后台访问接口,并不存在浏览器的跨域,一定要理解这点。
4、改写orgin
这种在webpack中已经是标配了,简单得不要不要的
devServer: { port: port, https: true, proxy: { '^/api': { target: 'https://test.qq.com', pathRewrite:{ '^/api','' }, changeOrigin: true, ws: true } }, disableHostCheck: process.env.NODE_ENV.startsWith('development') },
这么简单的背后,全是因为他。所以,你还是看到了node的影子,事实上就是用node起了一个server,做了转发而已。
可以看到,这种方式的成本是目前来说比较下的,但是还不至于说0配置。
比如,我们在开发环境中,就需要设置axios的baseUrl为'/api',然后上线设置为正式的baseUrl,才能应用这个代理规则。
总之,感觉都是比较麻烦。那么,有没有更加完美的方式呢?
完美级解决跨域
有的,直接改本地host文件,但是使用条件比较苛刻,条件是:
举个栗子,你测试环境是 https://test.qq.com,然后测试环境接口是https://mtest.qq.com/api/v,https://test.qq.com访问https://mtest.qq.com/api/v是配置了不跨域的。
此时,你可以修改你的host文件,加一个配置。
vim /etc/host 127.0.0.1 test.qq.com
此时你本地就,但是我们要面对两个问题。
1、现在测试环境配置一个https也是比较常见的,如何解决呢?
2、假如你有一个接口部署在https://test.qq.com上改怎么访问呢?
对于问题1.好说,启动是加上port参数 443,但是要sudo启动,对于问题2来说,就比较难解了,但是我们又很特殊,有现网环境,所以,我们配置一个proxy server 即可。
devServer: { port: 443, https: true, proxy: { '/pvp/share/getsharecfg': { target: 'https://qq.com', changeOrigin: true, ws: true } }, disableHostCheck: process.env.NODE_ENV.startsWith('development') },
对比上面方案4的好处是:
1、cookie是完美共享的,完全模拟了测试环境,有些时候,qq登录,微信登录需校验callbackurl,此时如果你用localhost显然是无法登录的,回调url不满足条件。
2、和测试环境完美一样,不但系发布到测试会有坑。
3、axios不需要依据开发环境不同配置不同baseUrl,比如之前开发环境就需要配置伪 baseUrl /api,也不需要写pathRewrite规则了,清爽太多。