浏览器多tab页面间的通信解决方案


若要实现两个互不相关的通源tab页面通信,可以使用一种比较巧妙的方式:localstorage。localStorage的存储遵循同源策略,因此同源的两个tab页面可以通过这种共享localStorage的方式实现通信,通过约定localStorage的某一个itemName,基于该key值的内容作为“共享硬盘”方式通信。


HTML5提供了storage事件,通过window对象监听storage事件,会侦听到localStorage对象的变化事件(setItem和removeItem)。因此通过事件可以完成高效的通信机制。


A 页面

window.addEventListener("storage", function(ev){
    if (ev.key == 'message') {
        // removeItem同样触发storage事件,此时ev.newValue为空
        if(!ev.newValue)
            return;
        var message = JSON.parse(ev.newValue);
        console.log(message);
    }
});

function sendMessage(message){
    localStorage.setItem('message',JSON.stringify(message));
    localStorage.removeItem('message');
}

// 发送消息给B页面
sendMessage('this is message from A');
B 页面

window.addEventListener("storage", function(ev){
    if (ev.key == 'message') {
        // removeItem同样触发storage事件,此时ev.newValue为空
        if(!ev.newValue)
            return;
        var message = JSON.parse(ev.newValue);
        // 发送消息给A页面
        sendMessage('message echo from B');
    }
});

function sendMessage(message){
    localStorage.setItem('message',JSON.stringify(message));
    localStorage.removeItem('message');
}

发送消息采用sendMessage函数,该函数序列化消息,设置为localStorage的message字段值后,删除该message字段。这样做的目的是不污染localStorage空间,但是会造成一个无伤大雅的反作用,即触发两次storage事件,因此我们在storage事件处理函数中做了if(!ev.newValue) return;判断。


当我们在A页面中执行sendMessage函数,其他同源页面会触发storage事件,而A页面却不会触发storage事件;而且连续发送两次相同的消息也只会触发一次storage事件。


通过这种方式,可以实现同源下的两个tab页通信

上一篇:解构流存储 — Pravega,与 Flink 构建端到端的大数据流水处理线


下一篇:kubectl基本操作