我们大多时把token存放在localStorage, 不过有时会导致浏览器重新开启请求某些API会401,需把token改存放在sessionStorage

2,156 阅读3分钟

如果我们只是单单把曾经存放在localStorage的token,改到sessionStorage,第一个页签正常登陆后操作是没问题,但是我们的项目网页通常需要多开标签页(分页),如果把token只是存在sessionStorage的话,用户重新开一个分页,就要重新登录(sessionStogage的特性只能在当前页签),如果token在localStorage的话就会全局共享

1.但前提是,token放在local已经不行(当前项目用户体验会差那么一丁点(但不影响使用)……我自己觉得),确定要放进session,这时我们可以监听"storage"来做一些事情

    // 该事件是核心 监听分页的情况
    window.addEventListener('storage',function(event){
    	// event.key确认修改的locaStorage变化key,event.newValue是修改后的值
        if(event.key =='xxxxx') {}
    })

2. 在浏览器中的多个tab页中共享数据,可以通过localStorage实现, 某些情况下,需要在浏览器关闭后即清除该数据,可以通过sessionStorage完成。但sessionStorage仅保存在当前tab页中,想要在多个tab中共享该数据,可通过localStorage实现。

  • 用户经常希望打开多个标签页。而此场景下将token保存在sessionStorage中将会带来很差的用户体验,每次开启一个标签页都会要求用户重新登录。没错,sessionStorage不支持跨标签页共享数据

  • sessionStorage在不同页面上不是同步共享的,但是我们有时候会将token或者一些登录凭证记录在token里,所以我们这里就写一下怎么将不同页面的sessionStorage同步更新,实现用户身份认证,并且可以保证用户不需要每次新开一个标签页都重新登录。

3. 利用localStorage事件来跨标签页共享sessionStorage

  • 当用户新开一个标签页时,我们先来询问其它已经打开的标签页是不是有需要给我们共享的sessionStorage数据。如果有,现有的标签页会通过localStorage事件来传递数据到新打开的标签页中,我们只需要复制一份到本地sessionStorage即可

  • 传递过来的sessionStorage绝对不会保存在localStorage,从localStorage事件将数据中复制并保存到sessionStorage,这个流程是在同一个调用中完成,没有中间状态。而且数据是对应事件携带的,并不在localStorage中

// 为了简单明了刪除了对IE的支持
(function(){

    if(!sessionStorage.length) {
        // 这个调用能触发目标事件,从而达到共享数据的目的
        localStorage.setItem('getSessionStorage',Date.now());
    };
    
    // 该事件是核心 监听分页的情况
    window.addEventListener('storage',function(event){

        if(event.key =='getSessionStorage') {
            // 已存在的标签页会收到这个事件
            localStorage.setItem('sessionStorage',JSON.stringify(sessionStorage));
            localStorage.removeItem('sessionStorage');
        
        } else if (event.key =='sessionStorage'&& !sessionStorage.length) {
            // 新开启的标签页會收到这个事件
            var value;
            var data = JSON.parse(event.newValue);
    
            // 这里面的key已经有token了,因为login登录时已经setItem过了
            for(key in data) {
                sessionStorage.setItem(key, data[key]);
            }
        } else if (event.key =='updateSession') {
            // 新登录的账号
            sessionStorage.setItem("token", event.newValue);
        } else if (event.key =='logoutSession') {
            // 退出账号
            sessionStorage.removeItem("token");
        }

    });
})();

4. 通过 localStorage.setItem("xxx") 来触发上面那些核心事件监听的"key"

// 第一步 页面登录
login:function () {
	 return new Promise(function (resolve, reject) {
            XXXX.session.login("xxx").done(function (rs) {
                sessionStorage.setItem("token", rs.value.token);
                localStorage.setItem("updateSession", rs.value.token);
    )}
}

// 退出账号
logout: function () { localStorage.setItem("logoutSession", Date.now()); }

// 项目里得到token
getToken: function () {
      return sessionStorage.getItem("token");
  },

5. sessionStorage可以看到当前页签下的所有session

// 这一块很重要能触发目标事件,从而达到共享数据的目的
if(!sessionStorage.length) {
      localStorage.setItem('getSessionStorage',Date.now());
  };
  
key = "getSessionStorage" 起到触发的作用

6. 重要 => 上面的方法是开分页,不同页面的监听,当在同一页面添加监听事件,监听 storage 并不起作用,要重写 storage 方法

重要 => blog.csdn.net/yotcap/arti…

[本文参考地址来自大佬]blog.kazaff.me/2016/09/09/…)

[本文参考地址来自缪运泽大佬]miaoyunze.com/2017/06/21/…)

结语

前端react QQ群:788023830 ---- React/Redux - 地下老英雄

前端交流 QQ群:249620372 ---- FRONT-END-JS前端

(我们的宗旨是,为了加班,为了秃顶……,仰望大佬),希望小伙伴们加群一起学习