前言
sessionStorage 属性允许你访问一个 session Storage 对象。它与 localStorage 相似,不同之处在于 localStorage 里面存储的数据没有过期时间设置,而存储在 sessionStorage 里面的数据在页面会话结束时会被清除。页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。**在新标签或窗口打开一个页面时会在顶级浏览上下文中初始化一个新的会话,**这点和 session cookies 的运行方式不同。
sessionStorage在页面会话结束时会被清除,也就是讲一个页面上的sessionStorage在页面刷新或者恢复页面的时候都不会丢失或者被清空。
但是,在同一个域下,不同的标签页,sessionStorage的信息不会被共享;如果是从一个标签页通过window.open等方式打开的新的标签页,会继承相同的sessionStorage。
如何共享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的回调