发表于: 2020-01-04 01:18:52
1 1345
今天完成的事情:
需求场景如下:在Vue项目中,调用的接口,需要用户登录后通过token进行访问,此时登录的相关页面部署在同域名的不同路径里,无法在当前项目访问到,我们要如何拿到这个登陆页面返回的token?接下来就跟大家分享一种解决方案,先看下最终实现的效果🤒
实现思路
- 页面创建完成后从本地存储中获取token
- 判断token是否存在
- 如果token不存在,则使用js弹出一个新的窗口打开登录页,如果token存在,则更新vuex中的token
- 在登陆页面中:登录成功获取token,将token存到本地存储中,关闭当前打开的窗口
- 监听到子窗口关闭,刷新当前窗口,更新vuex中的token
- 核心:将需要的数据存到本地存储中,Vue从本地存储中读取数据
实现过程
下面代码中有用到lodash库进行非空校验,需要使用yarn | npm安装这个库,接口调用进行了API抽离,本文不做讲解,关于API抽离的实现,可以参考我的另一篇文章 Vue合理配置axios并在项目中进行实际应用
// App.Vue created: function(){ // 页面创建完成后,从localstorage中获取token更新vuex const token = localStorage.getItem("token"); if(lodash.isEmpty(token)){ // 跳转登录页 let windowOBJ = this.openWin("https://www.kaisir.cn/login","loginWindow",800,675); // 使用定时器判断当前窗口是否关闭 let loop = setInterval(()=>{ if(windowOBJ.closed){ clearInterval(loop); // 刷新当前页 parent.location.reload(); } },1); }else{ // 更新vuex中的token this.$store.state.token = token; } }, // 方法 methods:{ // 居中打开一个新窗口 openWin:(url,name,iWidth,iHeight)=>{ //获得窗口的垂直位置 const iTop = (window.screen.availHeight - 30 - iHeight) / 2; // //获得窗口的水平位置 const iLeft = (window.screen.availWidth - 10 - iWidth) / 2; return window.open(url, name, `width=${iWidth},height=${iHeight},top=${iTop},left=${iLeft},toolbar:0`); } // 测试需要验证接口的调用 sendMessage:function(){ this.$api.websiteManageAPI.getJSON(1,3).then((res)=>{ console.log("接口调用成功"); console.log(res) }); } 复制代码
踩坑记录
子窗口关闭,刷新父页面
刚开始的想法是在子窗口中刷新父页面,然后关闭当前子窗口。结果浏览器报错:未捕获的DOMException:阻止了起源为“ www.kaisir.cn”的框架访问跨域框架。然后就使用定时器监听子窗口关闭,在父窗口实现刷新。当然你不考虑跨域问题的话,可以在登录页面实现父窗口的刷新
// 登录成功将token存储到本地存储,并刷新父页面 localStorage.setItem("token",res.token); opener.location.reload(); window.close(); 复制代码
- 正确的实现方式:使用定时器轮巡,监听子窗口的关闭,然后刷新当前页面,清理定时器
// 跳转登录页 let windowOBJ = this.openWin("https://www.kaisir.cn/login","loginWindow",800,675); // 使用定时器判断当前窗口是否关闭 let loop = setInterval(()=>{ if(windowOBJ.closed){ clearInterval(loop); // 刷新当前页 parent.location.reload(); } },1);
明天计划的事情:继续写后台
收获:更加了解了vue。
评论