跨页面通信、如何监听 LocalStorage 的变化【storage 事件】

场景:当涉及到同时打开多个tab页,操作一个tab,希望其他的tab也会同时进行更新状态。

原理就是前度的跨页面通信

一、【同源通信】LocalStorage

1 当 LocalStorage 变化时,会触发storage事件。

在需要改变的页面增加时间监听:

window.addEventListener('storage', function (e) {
    if (e.key === 'ctc-msg') {
        const data = JSON.parse(e.newValue);
        const text = '[receive] ' + data.msg + ' —— tab ' + data.from;
        console.log('[Storage I] receive message:', text);
    }
});
2 调用 window.localStorage.setItem() 触发更新。

这里需要注意,当两次 setItem 更新的值一样时,监听方法是不会触发的。

二、【非同源通信】iframe

我们有两个不同域名的产品线,也希望它们下面的所有页面之间能无障碍地通信。那该怎么办呢?

要实现该功能,可以使用一个用户不可见的 iframe 作为“桥”。由于 iframe
与父页面间可以通过指定origin来忽略同源限制,因此可以在每个页面中嵌入一个 iframe
(例如:http://sample.com/bridge.html),而这些 iframe 由于使用的是一个
url,因此属于同源页面,其通信方式可以复用上面第一部分提到的各种方式。 页面与 iframe 通信非常简单,首先需要在页面中监听iframe 发来的消息,做相应的业务处理:

/* 业务页面代码 */
window.addEventListener('message', function (e) {
    // …… do something
});

然后,当页面要与其他的同源或非同源页面通信时,会先给 iframe 发送消息:

/* 业务页面代码 */
window.frames[0].window.postMessage(mydata, '*');

复制代码其中为了简便此处将postMessage的第二个参数设为了’*’,你也可以设为 iframe 的 URL。 iframe
收到消息后,会使用某种跨页面消息通信技术在所有 iframe 间同步消息,例如下面使用的 Broadcast Channel:

/* iframe 内代码 */
const bc = new BroadcastChannel('AlienZHOU');
// 收到来自页面的消息后,在 iframe 间进行广播
window.addEventListener('message', function (e) {
    bc.postMessage(e.data);
});    

其他 iframe 收到通知后,则会将该消息同步给所属的页面:

/* iframe 内代码 */
// 对于收到的(iframe)广播消息,通知给所属的业务页面
bc.onmessage = function (e) {
    window.parent.postMessage(e.data, '*');
};

下图就是使用 iframe 作为“桥”的非同源页面间通信模式图。
在这里插入图片描述

参考链接:https://juejin.cn/post/6844903811232825357

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
监听 localStorage 变化,可以使用`window.addEventListener('storage', callback)`方法。这个方法会在 localStorage 中发生变化时触发回调函数。 在 MobX 中,可以使用`autorun`函数来监听 localStorage变化。`autorun`函数会自动追踪被观察的数据,并在它们发生变化时执行回调函数。 以下是一个使用 MobX 监听 localStorage 的例子: ```javascript import { autorun } from 'mobx'; // 定义一个 observable 对象 const storage = { value: localStorage.getItem('value') || '', setValue(newValue) { this.value = newValue; localStorage.setItem('value', newValue); }, }; // 使用 autorun 监听 storage.value 的变化 autorun(() => { console.log(`localStorage 中的 value 发生变化:${storage.value}`); }); // 修改 localStorage 中的 value storage.setValue('new value'); ``` 在这个例子中,我们先定义了一个 observable 对象 `storage`,它有一个属性 `value` 表示 localStorage 中的值。`setValue` 方法用于修改 `value` 值,并将修改后的值存储到 localStorage 中。 然后我们使用 `autorun` 函数来监听 `storage.value` 的变化。当 `storage.value` 发生变化时,`autorun` 函数会自动执行回调函数,输出变化后的值。 最后我们调用 `storage.setValue('new value')` 修改了 localStorage 中的 value 值,这时 `autorun` 函数会自动执行回调函数,输出新的值。 注意:`autorun` 函数会在组件挂载时自动执行一次回调函数,因此在上面的例子中,在控制台中会先输出 localStorage 中的 value 值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值