likes
comments
collection
share

跨页面通信有多少种技术方式可以实现?

作者站长头像
站长
· 阅读数 22

在日常开发中难免会遇到需要跨页面通信的场景,例如我们非常常见的登录场景,点击登录按钮后,将会打开一个新的页面去授权登录,当我们授权登录成功后,需要将授权信息传递给之前的页面,这个时候就需要跨页面通信了。

除了上述场景,还会有很多其他的场景需要跨页面通信,今天我们就来看看有哪些方式可以实现跨页面通信。

LocalStorage

LocalStorage 是 HTML5 中新增的一个 API,它可以用来在本地存储数据,它的特点是:

  • 存储的数据没有过期时间
  • 存储的数据大小为 5M
  • 存储的数据只能是字符串
  • 存储的数据会随着浏览器的关闭而清除

我们可以通过 window.localStorage 来访问 LocalStorage,它提供了一些方法来操作数据,例如:

  • setItem:用于存储数据
  • getItem:用于获取数据
  • removeItem:用于删除数据
  • clear:用于清空数据

这些都是我们常用的方法,今天不讲这些,而是正好localStorage的可以实现跨页面通信;

浏览器提供了一个事件 storage,当 localStorage 中的数据发生变化时,会触发这个事件,我们可以通过这个事件来监听数据的变化,从而实现跨页面通信。

window.addEventListener('storage', function (e) {
  console.log(e);
});

storage事件提供了一些属性,例如:

  • key:变化的数据的 key
  • newValue:变化后的数据
  • oldValue:变化前的数据

我们可以通过newValueoldValue来获取新旧数据,从而做一些自己的逻辑处理;

但是这种方式有一个缺点,就是只能在同一个域名下的页面之间通信,如果是不同的域名,是无法通信的(浏览器之间的各种通信都有这个问题);

同时如果修改的value没有任何变化的话,是不会触发storage事件的,这个可能没啥影响,但是如果你的业务逻辑需要这个的话,就需要注意了。

这里我之前写了一个案例和文章,可以参考:兔年到,一起来看看兔子家族都在聊些什么吧

SharedWorker

SharedWorker是我之前写的Web Worker专栏中的其中一个特性,这里就不展开讲解,就讲讲跨页面通信的实现方式;

SharedWorker是可以在多个页面之间共享的Worker,它的特点是:

  • 可以在多个页面之间共享
  • 可以在多个页面之间通信
  • 可以在多个页面之间共享数据

使用的时候只需要在页面中引入SharedWorker的脚本即可,然后通过new SharedWorker来创建一个SharedWorker实例,这个实例提供了一些方法,例如:

// 创建一个 SharedWorker 实例
const worker = new SharedWorker('worker.js');

// 向 SharedWorker 发送消息
worker.port.postMessage('hello');

// 监听 SharedWorker 的消息
worker.port.onmessage = function (e) {
  console.log(e.data);
};

这里的worker.js就是我们的SharedWorker脚本,它提供了一些方法,例如:

// 监听 SharedWorker 的消息
onconnect = function (e) {
  const port = e.ports[0];
  port.onmessage = function (e) {
    console.log(e.data);
    
    // 向 port 发送消息
    port.postMessage('world');
  };
};

这里因为之前写过,就不凑字数了,可以参考:💞💞💞SharedWorker 让你多个页面相互通信

BroadcastChannel

今天要讲的其实是BroadcastChannel,它是一个频道,可以向频道中发送消息,也可以监听频道中的消息;

当我们向频道中发送消息时,频道中的所有监听者都会收到消息,这样就可以实现跨页面通信了;

使用的时候不需要任何的配置或者脚本,只需要通过new BroadcastChannel来创建一个BroadcastChannel实例,然后通过postMessage来向频道中发送消息,通过onmessage来监听频道中的消息;

// 创建一个 BroadcastChannel 实例
const channel = new BroadcastChannel('channel');

// 向频道中发送消息
channel.postMessage('hello');

// 监听频道中的消息
channel.onmessage = function (e) {
  console.log(e.data);
};

这个其实和Worker的通信方式很像,只不过Worker是在同一个页面中,而BroadcastChannel是在不同的页面中;

首先我们通过new BroadcastChannel来创建一个BroadcastChannel实例,给它传递的参数就是频道的名称,这个名称是可以自定义的,只要保证不同的页面中使用的名称是一样的即可;

然后我们通过postMessage来向频道中发送消息,通过onmessage来监听频道中的消息;

可以看我下面的一个简单的示例:

BroadcastChannelAPI非常简单,发送消息就是postMessage,监听消息就是onmessage,然后还有一个close方法,用于关闭频道;

这里有一个坑,就是BroadcastChannel是需要在页面关闭的时候手动关闭的,否则会导致内存泄漏,所以我们需要在页面关闭的时候手动关闭它;

window.addEventListener('beforeunload', function () {
  channel.close();
});

因为BroadcastChannel是一个广播频道,所以浏览器不知道你什么时候不需要它了,所以需要我们手动关闭它;

总结

今天我们讲了一下跨页面通信的三种方式,分别是localStorageSharedWorkerBroadcastChannel

localStorage是通过监听storage事件来实现的,使用起来非常简单,缺点是只能传递字符串;

SharedWorker是可以在多个页面之间共享的Worker,它的特点是可以在多个页面之间共享和通信,使用起来稍微复杂一点,但是功能也比较强大;

BroadcastChannel是一个频道,可以向频道中发送消息,也可以监听频道中的消息,使用起来简直不用太方便,但是需要注意的是需要手动关闭它;

在日常开发中如果对于兼容性要求非常高的话,可以使用localStoragelocalStorage兼容性直接无障碍;

如果对于兼容性要求不高的话,可以使用BroadcastChannel,它的兼容性还是很不错的,在chrome 54之后就支持了,而且使用起来也非常简单;

如果对于兼容性要求不高的话,还可以使用SharedWorker,它的兼容性还算可以,但是使用起来稍微复杂一点,而且功能也比较强大;

转载自:https://juejin.cn/post/7212427549610246205
评论
请登录