跨页面通信

Posted by CodingWithAlice on June 29, 2021

跨页面通信(7种)

参考文章:跨页面通信

两个页面之间的通信会涉及到同源策略的限制,所以按照是否满足同源策略的限制分成两大部分来看。

同源页面间的通信

1-3 三种类型都是有一个“中央站”的概念,由中央站再通知给各个页面

1/6、广播式通信 BroadCast Channel

主要参考文章:

核心要点:

  • 所有页面都监听同一频道的消息,其中某一个页面通过它发送的消息就会被其他所有页面收到

注意:两个页面都需要对同一个频道实例化

// 页面1
const ling = new BroadcastChannel('junZhe');//实例化
/* 发送消息 */
ling.postMessage('是真的!');
// 页面2
const ling = new BroadcastChannel('junZhe');//实例化
/* 监听被广播的消息 - 也可以使用 addEventListener 来监听 message */
ling.onmessage = function (e) {
    const data = e.data;// 是真的!
};

2/6、消息中转站 Service Worker

主要参考文章:

核心要点:

  • Service Worker只能运行在 HTTPSlocalhost(127.0.0.1) 域下
  • Service Worker的各类操作都被设计为异步 Promise,用以避免一些长时间的阻塞操作

【没有进行实践】

3/6、LocalStorage

localstorage 是浏览器 多个标签共用 的存储空间,所以可以用来实现多标签之间的通信

(ps:session 是会话级的存储空间,每个标签页都是单独的

window.onstorage = (e) => {console.log(e)}
// 或者这样
window.addEventListener('storage', (e) => console.log(e))

核心要点:

  • 特点1:onstorage 以及 storage 事件,针对都是 非当前页面 对 localStorage 进行修改时才会触发,当前页面修改 localStorage 不会触发监听函数
  • 特点2:在对原有的数据的值进行 修改时才会触发,比如原本已经有一个 key=a,value=b 的 localStorage,你再执行:localStorage.setItem('a', 'b')是不会触发监听函数的
// 页面1-监听 localstroage 的变化
window.addEventListener('storage', function (e) {
    if (e.key === 'junzhe') {
        const data = JSON.parse(e.newValue); 
        // {message: '是真的', ts: 1625054508019}
    }
});
// 页面2-改变 LocalStorage -> 加 ts 是因为 storage 事件只在 值 真正改变时触发
let ts = +new Date();
let data = {
    message: '是真的',
    ts,
};
localStorage.setItem('junzhe', JSON.stringify(data));

4/6、Shared Worker

普通的 webworker 直接使用 new Worker() 即可创建,这种 webworker 是 当前页面 专有的。

然后还有种共享 worker(SharedWorker),这种是可以多个标签页、iframe共同使用的

核心要点:

  • 多个 Tab 注册的 Shared Worker 可以实现数据共享
  • 无法主动通知所有页面,使用 轮询 的方式拉取最新的数据

【没有进行实践】

5/6、定时器 + IndexedDB/cookie - 轮询

核心要点:

①在页面A设置一个使用 setInterval 定时器不断刷新,检查 Cookies/IndexedDB 的值是否发生变化,如果变化就进行刷新的操作

②由于 Cookies 是在 同域可读 的,所以在页面 B 审核的时候改变 Cookies 的值,页面 A 自然是可以拿到的

6/6、通过 window.open 实现

核心要点:

  • 通过 A 页面打开 B 页面,可以形成页面树状结构

缺点:如果 B 页面不是从 A 页面打开的,就失去了结构

非同源页面间的通信

通过 iframe 转换成同源页面通信

核心要点:

  • 由于 iframe 与父页面间可以通过指定 origin 来忽略同源限制,因此可以在每个页面中嵌入同一个 iframe —> 这些 iframe 由于使用的是一个 url,因此属于同源页面,其通信方式可以复用上面第一部分提到的各种方式