不同页面之间的通信方式
前言
当需要在一个浏览器中的不同页面(tabs,iframes)进行通信时,我们可以使用如下方法。首先根据同源与否,分为同源和非同源。
一、同源
1.使用BroadCast Channel
BroadCast Channel
可以为我们创建一个公共的广播频段,当不同的页面都监听他时,就可以收到其他页面发出的消息。
使用方法:
const bc = new BroadcastChannel('AlienZHOU');
// 发消息
bc.postMessage(mydata);
// 监听
bc.onmessage = function (e) {
const data = e.data;
const text = '[receive] ' + data.msg + ' —— tab ' + data.from;
console.log('[BroadcastChannel] receive message:', text);
};
2.Service Worker
Service Worker
是一个运行在后台的worker
(类比web worker
),他可以充当广播的作用,为不同页面传递消息。
1.注册 Service Worker
:
/* 页面逻辑 */
navigator.serviceWorker.register('../util.sw.js').then(function () {
console.log('Service Worker 注册成功');
});
其中../util.sw.js
是对应的 Service Worker
脚本。Service Worker
本身并不自动具备“广播通信”的功能,需要我们添加些代码,将其改造成消息中转站:
/* ../util.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(function (client) {
client.postMessage(e.data);
});
})
);
});
在页面中监听
/* 页面逻辑 */
navigator.serviceWorker.addEventListener('message', function (e) {
const data = e.data;
const text = '[receive] ' + data.msg + ' —— tab ' + data.from;
console.log('[Service Worker] receive message:', text);
});
在页面中发送消息
/* 页面逻辑 */
navigator.serviceWorker.controller.postMessage(mydata);
3.监听localStorage
当 LocalStorage
变化时,会触发storage
事件。利用这个特性,我们可以在发送消息时,把消息写入到某个 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);
}
});
设置值:
mydata.st = +(new Date); // 取当前毫秒时间戳的.st属性
window.localStorage.setItem('ctc-msg', JSON.stringify(mydata));
二、非同源
因为iframe
与父页面间可以通过指定origin
来忽略同源限制非同源页面之间的通信,我们可以通过iframes
来当做消息转发的桥梁。
因此可以在每个页面中嵌入一个 iframe
(例如:http://sample.com/bridge.html
),而这些 iframe
由于使用的是一个 url
,因此属于同源页面,其通信方式可以复用上面第一部分提到的各种方式。
参考博文:
[1]: https://juejin.cn/post/6844903811232825357#heading-11
[2]: https://juejin.cn/post/6844903997103423501