在日常开发中难免会遇到需要跨页面通信的场景,例如我们非常常见的登录场景,点击登录按钮后,将会打开一个新的页面去授权登录,当我们授权登录成功后,需要将授权信息传递给之前的页面,这个时候就需要跨页面通信了。
除了上述场景,还会有很多其他的场景需要跨页面通信,今天我们就来看看有哪些方式可以实现跨页面通信。
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
:变化的数据的 keynewValue
:变化后的数据oldValue
:变化前的数据
我们可以通过newValue
和oldValue
来获取新旧数据,从而做一些自己的逻辑处理;
但是这种方式有一个缺点,就是只能在同一个域名下的页面之间通信,如果是不同的域名,是无法通信的(浏览器之间的各种通信都有这个问题);
同时如果修改的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'); }; };
这里因为之前写过,就不凑字数了,
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
来监听频道中的消息;
可以看我下面的一个简单的示例:
BroadcastChannel
的API
非常简单,发送消息就是postMessage
,监听消息就是onmessage
,然后还有一个close
方法,用于关闭频道;
这里有一个坑,就是BroadcastChannel
是需要在页面关闭的时候手动关闭的,否则会导致内存泄漏,所以我们需要在页面关闭的时候手动关闭它;
window.addEventListener('beforeunload', function () { channel.close(); });
因为BroadcastChannel
是一个广播频道,所以浏览器不知道你什么时候不需要它了,所以需要我们手动关闭它;
总结
今天我们讲了一下跨页面通信的三种方式,分别是localStorage
、SharedWorker
和BroadcastChannel
;
localStorage
是通过监听storage
事件来实现的,使用起来非常简单,缺点是只能传递字符串;
SharedWorker
是可以在多个页面之间共享的Worker
,它的特点是可以在多个页面之间共享和通信,使用起来稍微复杂一点,但是功能也比较强大;
BroadcastChannel
是一个频道,可以向频道中发送消息,也可以监听频道中的消息,使用起来简直不用太方便,但是需要注意的是需要手动关闭它;
在日常开发中如果对于兼容性要求非常高的话,可以使用localStorage
,localStorage
兼容性直接无障碍;
如果对于兼容性要求不高的话,可以使用BroadcastChannel
,它的兼容性还是很不错的,在chrome 54
之后就支持了,而且使用起来也非常简单;
如果对于兼容性要求不高的话,还可以使用SharedWorker
,它的兼容性还算可以,但是使用起来稍微复杂一点,而且功能也比较强大;