BroadcastChannel
Broadcast Channel API 可以实现同源下浏览器不同窗口、Tab 页或者 iframe 下的浏览器上下文之间的简单通讯。通过创建一个监听某个频道下的 BroadcastChannel 对象,你可以接收发送给该频道的所有消息。
语法
更多内容看这里:传送门
案例
const bc = new BroadcastChannel('fm86.7');
bc.onmessage = function (ev) {
alert(ev.data);
}
bc.postMessage('Music Radio');
const bc = new BroadcastChannel('fm86.7');
bc.onmessage = function (ev) {
alert(ev.data);
}
const bc = new BroadcastChannel('fm86.7');
bc.onmessage = function (ev) {
alert(ev.data);
}
从代码可以看出,三个页面都接入了fm86.7频道,A广播了Music Radio字符串,B和C都会接收到,且alert出来。
兼容性
注意事项
- BroadcastChannel仅局限于本域,不支持跨域。
postMessage
window.postMessage一般用于定向传递数据,而且可以实现跨域交互(可以设置targetOrigin保证安全)。
语法
window.postMessage(msg,targetOrigin)
msg:这就是要传递的消息。它可以是一切javascript参数,如字符串,数字,对象,数组,而不是和json一样只局限于字符串。
targetOrigin:这个参数称作“目标域”。
- 注意啦,是目标域不是本域!比如,你想在2.com的网页上往1.com网页上传消息,那么这个参数就是1.com/,而不是2.com。
- 一个完整的域包括:协议,主机名,端口号。如:g.cn:80/
更多内容看这里:传送门
案例
const B = window.open(B.html);
B.postMessage("hello B!", "*");
function receiveMessage(event) {
//event.origin是指发送的消息源,一定要进行验证!!!
if (event.origin !== "http://localhost")return;
//event.data是发送过来的消息。
console.log(event.data);
}
window.addEventListener("message", receiveMessage, false);
兼容性
注意事项
- 注意postMessage要通过window对象调用。
- 因为这里的window不只是当前window,大部分使用postMessage的时候,都不是本页面的window,而是其他网页的window。
- 比如:
- iframe的contentWindow
- 通过window.open方法打开的新窗口的window
- window.opener
- 如果你使用postMessage时没有带window,那么,你就是用的本页面的window来调用了它。
localStorage
本方式,同样适用于sessionstorage、IndexedDB、Cookie等。
语法
更多内容看这里:传送门
案例
function populateStorage() {
localStorage.setItem('abc','123');
}
window.addEventListener('storage', function(e) {
console.log(e.key); // abc,该属性代表被修改的键值。当被clear()方法清除之后该属性值为null。(只读)
console.log(e.oldValue); // nul,该属性代表修改前的原值。在设置新键值对时由于没有原始值,该属性值为 null。(只读)
console.log(e.newValue); // '123',修改后的新值。如果该键被clear()方法清理后或者该键值对被移除,,则这个属性为null。
console.log(e.url); // http://localhost:8000/a,发生改变的对象所在文档的URL地址。(只读)
console.log(e.storageArea); // 当前的localStorage里的内容,对象形式返回
});
兼容性
注意事项
- 两个页面要同源(URL的协议、域名和端口相同)
- 当前页面订阅storage事件并触发setItem是不会生效的。
- 符合同源策略,在同一浏览器下的不同窗口, 当焦点页以外的其他页面导致数据变化时,如果焦点页监听storage事件,那么该事件会触发
- 换一种说法就是除了改变数据的当前页不会响应外,其他窗口都会响应该事件。
MessageChannel
MessageChannel API可以让运行在不同浏览器上下文中的独立脚本,连接到同一份文档(比如:两个 IFrame, 或者主文档和一个 IFrame, 或者使用同一个 SharedWorker 的两份文档),并直接通信,通过每端一个 port 的双向频道(或管道)在两者之间传递消息。
语法
更多内容看这里:传送门
案例
const { port1, port2 } = new MessageChannel();
port1.onmessage = function (d) {
console.log(`port1接收的消息是:${d.data}`);
};
port2.onmessage = function (d) {
console.log(`port2接收的消息是:${d.data}`);
};
// 发送消息
console.log(port1, port2);
port1.postMessage('port1发送的消息');
port2.postMessage('port2发送的消息');
port2.postMessage('port2发送的消息');
MessageChannel创建了一个通信的管道,这个管道有两个端口,每个端口都可以通过postMessage发送数据,而一个端口只要绑定了onmessage回调方法,就可以接收从另一个端口传过来的数据。
兼容性
注意事项
- 可以通过SharedWorker实现跨域通信,可是SharedWorker的兼容性堪忧。
SharedWorker
语法
更多内容看这里:传送门
案例
待完善
兼容性
注意事项
- 虽然功能强大,但兼容性堪忧。
WebSocket
所有的WebSocket都监听同一个服务器地址,利用send发送消息,利用onmessage获取消息的变化,不仅能窗口,还能跨浏览器,兼容性最佳,只是需要消耗点服务器资源。
语法
更多内容看这里:传送门
案例
var ws = new WebSocket("ws://localhost:3000/")
ws.onopen = function (event) {
// 或者把此方法注册到其他事件中,即可与其他服务器通信
ws.send({now : Date.now()}); // 通过服务器中转消息
};
ws.onmessage = function (event) {
// 消费消息
console.log(event.data);
}
兼容性
注意事项
- 需要起一个后端服务做桥梁
参考文章
postMessage相关
- 两个浏览器窗口间通信总结
- 微前端?
- 页面间交互——window.postMessage和Broadcast Channel API
- 七日打卡-窗口间通信postMessage
- HTML5 postMessage iframe跨域web通信简介