发表于: 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。


返回列表 返回列表
评论

    分享到