跨tab通信【1】之同源策略

95 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情

一切来自于今天在前端交流群里w哥的一句灵魂发问:

image.png

> 多个tab页之间的信息互通各位有啥想法

iframe

首先想到的是iframe

什么是 iframe

这个HTML元素表示嵌套的浏览上下文,将另一个 HTML 页面嵌入到当前页面中。
每个嵌入式浏览上下文都有自己的[会话历史记录]和[文档]。嵌入其他浏览上下文的浏览上下文称为父浏览上下文。浏览上下文(没有父级的上下文)通常是浏览器窗口,由[Window]对象表示。

跨tab通信?

跨tab通信包括两种方式:同源和不同源。

什么是同源?

端口 域名 协议三者相同便是同源。

同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

同源下的跨tab通信

可以使用浏览器自带的localstorage进行通信。

什么是localStorage?

在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同。

localStorage的优缺点

localstorage 遵循同源策略,因此在通信上只要遵循着同一个的itemName就可以了,使用方便。 但是方便带来的问题是通信效率的低下,需要通信双方不听的监听localstorage的变化。
这时候可以使用window对象监听localstorage事件的变化。

TAB 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 the message from A');

tabB 的监听如下:

//tab B

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

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

这里为了不污染localstorage的空间,所以删除了message导致了触发了两次的storage事件,不得不说是有舍必有得。

下期预告

同源通信解决了,那么非同源的tab通信该怎么实现呢?
请听下回分解。

我是短袖撸码蒂尔尼
一名热爱阿森纳的前端工程师
如果本文对您有帮助,可以给一个免费的赞吗?谢谢!

名片.jpg