sessionStorage共享(监听storage事件)

前言

sessionStorage 属性允许你访问一个 session Storage 对象。它与 localStorage 相似,不同之处在于 localStorage 里面存储的数据没有过期时间设置,而存储在 sessionStorage 里面的数据在页面会话结束时会被清除。页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。**在新标签或窗口打开一个页面时会在顶级浏览上下文中初始化一个新的会话,**这点和 session cookies 的运行方式不同。

sessionStorage在页面会话结束时会被清除,也就是讲一个页面上的sessionStorage在页面刷新或者恢复页面的时候都不会丢失或者被清空。

但是,在同一个域下,不同的标签页,sessionStorage的信息不会被共享;如果是从一个标签页通过window.open等方式打开的新的标签页,会继承相同的sessionStorage。

Storage Event - MDN

如何共享sessionStorage信息

原理

根据Web Storage API,监听storage事件;

启动本地服务,在两个标签页打开该文件,点击一个页面的“setItem”div,另一个页面便会在console输出object:{event}信息。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
</head>
<body>
    <div onclick="set()">setItem</div>
    <script>
        function set(){
            localStorage.setItem("key", new Date());
        }
        window.addEventListener("storage", function(event){
            console.log('object:', event)
        })
    </script>
</body>
</html>

实现

假设tabA标签页已经登录,存储了session信息;

那么,在新的标签页tabB打开相同的地址:

  • tabB判断session没有userInfo,则在localStorage设置getSessionStorage
  • 由于tabA已经监听了storage事件,当上一步设置了localStorage时,tabA执行事件的handler,将session设置到localStorage当中
  • tabA设置localStorage,便会触发tabB的事件执行。在tabB中将event.newValue设置到sessionStorage中
  • 最后,删除localStorage中的信息。
if(!sessionStorage.userInfo) {
    localStorage.setItem('getSessionStorage',Date.now());
}
window.addEventListener('storage',function(event){
    if(event.key =='getSessionStorage') {
        localStorage.setItem('userInfo', sessionStorage.getItem("userInfo"));
        localStorage.removeItem('userInfo');
    } else if(event.key =='userInfo' && event.newValue) {
        sessionStorage.setItem("userInfo",event.newValue);
    }
});

应用

在实际开发过程当中,需要在入口文件当中判断用户是否登录checkLogin;所以获取session信息要在checkLogin之前进行。但是,eventListener是异步触发的,会导致session还没有获取到时,便执行了checkLogin;

所以可以用promise对上面函数进行封装。

async function checkSession(){
    return new Promise(resolve => {
        if(!sessionStorage.userInfo || Object.keys(JSON.parse(sessionStorage.userInfo)).length === 0) {
            localStorage.setItem('getSessionStorage',Date.now());
        }else{
            resolve();
        }
        window.addEventListener('storage',function(event){
            if(event.key =='getSessionStorage') {
                localStorage.setItem('userInfo', sessionStorage.getItem("userInfo"));
                localStorage.removeItem('userInfo');
            } else if(event.key =='userInfo' && event.newValue) {
                sessionStorage.setItem("userInfo",event.newValue);
                resolve();
            }
        });
    })
}
async function main(){
    await checkSession();
    checkLogin();
}
main();

注:

  • storage事件只能监听到localStorage的变化
  • 当前页面修改localStorage时,当前页面不会触发storage回调执行;如果另一个同源的页面监听了storage事件,那么这个页面会执行storage的回调
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值