前言:
跨页面通信是为了两个不同的页面之间的通信问题,在浏览器中,我们可以同时打开多个Tab页,每个Tab页可以粗略理解为一个“独立”的运行环境,即使是全局对象也不会在多个Tab间共享。然而有些时候,我们希望能在这些“独立”的Tab页面之间同步页面的数据、信息或状态。
同源跨页面通信方法:
BroadcastChannel:
BrocastChannel可以实现同源下浏览器不同窗口,tab页,frame或frame下的浏览器上下文之间的通信,可以实现在同源的多个页面之间广播消息的机制。
// a页面
const bc = new BroadcastChannel('broadcast')
bc.postMessage('发送数据')
// b页面
const bc = new BroadcastChannel('broadcast')
bc.onmessage = function(e) {
console.log(e)
}
/** 消息发送后,所有连接到该频道的 BrocastChannel对象上都会触发 meaasge事件,
该事件没有默认行为,可以使用`onmessage`事件处理程序来定义一个函数处理消息
**/
localStorage:
localStorage是HTML5引入的客户端存储方案,通过localStorage存储的内容会一直保存在客户端,除非调用removeItem方法显式移除,否则内容将永久保留。MDN上对localStorage的介绍也提到了一种通过cookie在不支持localStorage的浏览器上实现localStorage的方法,通过将cookie的过期时间设置为未来很长之后的一个时间点可以模拟localStorage永久保留的特性,而在模拟localStorage移除存储内容时则将对应的cookie删除。更进一步,如果不设置cookie的过期时间,还可以用来模拟浏览器中的另一种客户端存储方案–sessionStorage。和cookie不同的是,localStorage提供的存储容量上限更大。
// a页面
window.addEventListener('storage', function(e) {
console.log(e)
})
// b页面
localStorage.setItem('data', 10000)
在浏览器的多个标签页中分别打开多个同源页面,当其中某个页面在localStorage中添加、修改或删除某些字段或清空存储的内容时,会触发其他页面中的window对象监听的storage事件(当前修改localStorage的页面不触发),通过这种方式也可以实现跨页面通信。
Service Worker:
Service Worker 是一个可以长期运行在后台的Worker,能够实现与页面的双向通信。多页面共享间的 Service Worker 可以共享,将 Service Worker 作为消息的处理中心(中央站)即可实现广播效果。
- 首先在页面注册 Service Worker:
/* 页面逻辑 */
navigator.serviceWorker.register('./sw.js').then(function () {
console.log('Service Worker 注册成功');
});
- 其中./sw.js是对应的 Service Worker 脚本。Service Worker 本身并不自动具备“广播通信”的功能,需要我们添加些代码,将其改造成消息中转站:
/* ./sw.js Service Worker 逻辑 */
self.addEventListener('message', function (e) {
console.log('service worker receive message', e.data);
e.waitUntil(
self.clients.matchAll().then(function (clients) {
if (!clients || clients.length === 0) {
return;
}
clients.forEach(