iframe + postMessage + localStorage 实现多标签页信息同步

需求背景:

  存在多个项目(顶级域名相同.scc.com),当打开多个tab页时,我在一个页面退出登录,其他页面同步信息,页面弹出已登出提示。

 

实现方式 iframe + postMessage + localStorage

 

如有三个已登陆的页面 A1 A2 B1

页面A1: http://a1.scc.com

页面A2: http://a2.scc.com

页面B1: http://b1.scc.com

一个空的iframe页面: http://static.scc.com/iframe.html

 

http://static.scc.com/iframe.html 内容如下

<html>
<body>
    <script>
        window.addEventListener("storage", function (ev) {
            ev = window.event || ev
            if (ev.key == "scc_message") {
                window.parent.postMessage(ev.newValue, "*");
            }
        });

        function postMessageToStorage(message) {
            localStorage.setItem("scc_message", JSON.stringify(message));
            localStorage.removeItem("scc_message");
        }

        window.addEventListener("scc_message", function (ev) {
            ev = window.event || ev
            let data = ev.data;
            postMessageToStorage(data);
        });

    </script>
</body>
</html>

  

页面 A1 A2 B1 代码相同

DOM引入iframe标签

<iframe id="sccproxy" src="//static.scc.com/iframe.html" style="width:0px;height:0px;frameBorder:0"></iframe>
<div v-if=flag">
    <h3><i></i><span >登录状态已改变</span></h3>
    <p>当前账号的登录状态已改变,页面即将刷新。</p>
    <div><a href="/">确定</a></div>
</div>
<button @click="sendMessageToTab({type:''sccExit})">退出登录<button>

js代码 

data () {
  return {
    flag:false
  }
}
mounted () {
   this.addMessageListener ()
},
methods: {
 addMessageListener ()  {
   let _this = this
     window.addEventListener("message", function (ev) {
        ev = window.event || ev
        let data = ev.data;
        let source = ev.source;
        let origin = ev.origin;
        if (!data) return;
        if (origin.indexOf("//static.scc.com") >= 0) {
          try {
            let info = JSON.parse(JSON.parse(data));
            if (info.type == "sccExit" && !document.hasFocus()) {
              _this.flag = true
            }
        } catch (e) {
          console.log(e)
        }
      }
    });
 },
 sendMessageToTab (data) {
  try {
        document.querySelector("#sccproxy").contentWindow.postMessage(JSON.stringify(data), 'http://static.scc.com');
      } catch (err) {
        console.log(err)
      }
  }
}

  

posted @ 2019-12-17 17:43  cc_loving  阅读(1211)  评论(0编辑  收藏  举报