跨域这个问题,可以说是前端的必需了解的,但是多少人是知其然不知所以然呢? 下面我们来梳理一下vue解决跨域的思路。
什么情况会跨域?
跨域的本质就是浏览器基于同源策略的一种安全手段。所谓同源就是必须有以下三个相同点:协议相同、域名相同、端口相同。如果其中有一项不同,即出现非同源请求,就会产生跨域。
跨域实际上是浏览器的限制,开发中使用 postman请求接口能够获得数据就印证了跨域是浏览器的限制这个问题。
那浏览器为什么要弄个跨域出来?
总的来说:浏览器跨域机制的主要目的是保护用户的安全和隐私.
为什么说跨域能保护用户的隐私呢 ? 比如说你打开了某个银行的官网 xxyh.com,然后又打开了一个恶意网站 xxxx.com,此时两个网站的域名肯定是不同的,这时候这个恶意的网站想从你银行网站中获取你的cookie等个人信息,那么浏览器就会阻止它的请求.
我们开发过程中为什么会出现跨域?
刚才说了,协议、端口、域名,只要有一个不同,请求就会跨域。而我们开发中,项目运行在http://localhost:3000 上,这时候协议是 http,端口是 3000,域名是 localhost。而我们的请求一般是发到了后端给的服务器API地址,这时候协议端口域名出现不同了就会跨域 !
解决方法
一般前端中解决跨域问题的方法有 JSONP,CROS,Proxy等,这里我们主要讲解一下在 vue中常用的 CORS方法:
一般来说,我们会在vue.config.js中配置proxy反向代理来解决跨域,但是解决的逻辑是怎样的呢?
拿我的项目来举例:首先,我们要知道proxy中代码的作用:
// 接口转发 proxy: { '/dev': { target: APIURl, // 后端服务器的地址 changeOrigin: true, // 设置为 true,允许跨域 pathRewrite: { '^/dev': '' // 可选的,重写请求路径,如果后端接口的路径中有特定的前缀,可以进行替换 } } } '/dev',这里指定了一个路径匹配规则,当前端发起的请求路径以'/dev'开头的时候会触发反向代理配置.
所以想要发起的请求走反向代理,就需要我们的请求是以'/dev'开头,但是我们封装的api的路径里面好像并没有开头写上'/dev',而且如果每个api都需要带上'/dev'的话,那需要在封装axios请求的时候每次在路径前面加上'/dev'也太麻烦了吧.
于是,我们可以在请求拦截器中设置请求的基地址为'/dev',然后每次请求都自动在请求路径前面带上了'/dev',就完成了每次请求都走反向代理这个需求.
请求拦截器 request:
我的基地址是配置在环境变量中的,他在环境变量中是:
也就等价于:
const service = axios.create({ baseURL:'/dev', // url = base url + request url withCredentials: false, // send cookies when cross-domain requests timeout: define.timeout, // request timeout })
这样,我们就给每个请求路径前面都加上了'/dev',然后在vue.config.js中,proxy发现我们的请求是'/dev'开头的,就会将我们的请求代理到:
target: APIURl, // 填你后端服务器的地址
并且设置:
changeOrigin: true, // 设置为 true,允许跨域
然后这个配置的作用:
pathRewrite: { '^/dev': '' // 可选的,重写请求路径,如果后端接口的路径中有特定的前缀,可以进行替换 }
因为我们前面说了,'/dev'这个字符串的作用只是一个标识,我们给每个请求的开头都加上这个标识,就能够被反向代理识别到然后就能允许跨域 , 而后端给我的实际请求路径中是没有'/dev'的,所以,我们在他进入反向代理后,又要将他重写为 ' ', 让他不影响真正的请求路径.
举个例子:反向代理就像一个保安,每天都有很多人要从代理过去,但是保安怎么分辨出哪些请求是要让他通过的呢? 这时候领导和保安说,你看到那些人手里拿着员工牌牌(‘/dev’)的就让他通过,而我们在请求拦截器中给每个请求前加上了'/dev' ,所以我们的请求就都能代理到真实请求的服务器上去啦 !
然后,既然跨域是浏览器的保护机制,那么我们是不是可以将自己浏览器的保护机制关了,让我们在开发中可以直接发起跨域请求呢?
可以! 看我的这篇文章 :
谷歌关闭跨域限制.(生成一个开发浏览器),Chrome关闭跨域
希望对你有用! ! !
有用的话别忘了点赞哦 ! ! !