心态决定成败,愿你以一个好的心态面对未来的生活😁
前言
需求场景如下:在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:阻止了起源为“ https://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);
写在最后
- 文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊
- 本文首发于掘金,如需转载请评论区留言💌
评论区