BroadcastChannel

Broadcast Channel API 可以实现同源下浏览器不同窗口、Tab 页或者 iframe 下的浏览器上下文之间的简单通讯。通过创建一个监听某个频道下的 BroadcastChannel 对象,你可以接收发送给该频道的所有消息。

语法

更多内容看这里:传送门

案例

  1. const bc = new BroadcastChannel('fm86.7');
  2. bc.onmessage = function (ev) {
  3. alert(ev.data);
  4. }
  5. bc.postMessage('Music Radio');
  1. const bc = new BroadcastChannel('fm86.7');
  2. bc.onmessage = function (ev) {
  3. alert(ev.data);
  4. }
  1. const bc = new BroadcastChannel('fm86.7');
  2. bc.onmessage = function (ev) {
  3. alert(ev.data);
  4. }

从代码可以看出,三个页面都接入了fm86.7频道,A广播了Music Radio字符串,B和C都会接收到,且alert出来。

兼容性

image.png

注意事项

  1. BroadcastChannel仅局限于本域,不支持跨域。

postMessage

window.postMessage一般用于定向传递数据,而且可以实现跨域交互(可以设置targetOrigin保证安全)。

语法

  1. window.postMessage(msg,targetOrigin)

msg:这就是要传递的消息。它可以是一切javascript参数,如字符串,数字,对象,数组,而不是和json一样只局限于字符串。

targetOrigin:这个参数称作“目标域”。

  • 注意啦,是目标域不是本域!比如,你想在2.com的网页上往1.com网页上传消息,那么这个参数就是1.com/,而不是2.com。
  • 一个完整的域包括:协议,主机名,端口号。如:g.cn:80/

更多内容看这里:传送门

案例

  1. const B = window.open(B.html);
  2. B.postMessage("hello B!", "*");
  1. function receiveMessage(event) {
  2. //event.origin是指发送的消息源,一定要进行验证!!!
  3. if (event.origin !== "http://localhost")return;
  4. //event.data是发送过来的消息。
  5. console.log(event.data);
  6. }
  7. window.addEventListener("message", receiveMessage, false);

兼容性

image.png

注意事项

  1. 注意postMessage要通过window对象调用。
    • 因为这里的window不只是当前window,大部分使用postMessage的时候,都不是本页面的window,而是其他网页的window。
    • 比如:
      • iframe的contentWindow
      • 通过window.open方法打开的新窗口的window
      • window.opener
    • 如果你使用postMessage时没有带window,那么,你就是用的本页面的window来调用了它。

localStorage

本方式,同样适用于sessionstorage、IndexedDB、Cookie等。

语法

更多内容看这里:传送门

案例

  1. function populateStorage() {
  2. localStorage.setItem('abc','123');
  3. }
  1. window.addEventListener('storage', function(e) {
  2. console.log(e.key); // abc,该属性代表被修改的键值。当被clear()方法清除之后该属性值为null。(只读)
  3. console.log(e.oldValue); // nul,该属性代表修改前的原值。在设置新键值对时由于没有原始值,该属性值为 null。(只读)
  4. console.log(e.newValue); // '123',修改后的新值。如果该键被clear()方法清理后或者该键值对被移除,,则这个属性为null。
  5. console.log(e.url); // http://localhost:8000/a,发生改变的对象所在文档的URL地址。(只读)
  6. console.log(e.storageArea); // 当前的localStorage里的内容,对象形式返回
  7. });

兼容性

image.png

注意事项

  1. 两个页面要同源(URL的协议、域名和端口相同)
  2. 当前页面订阅storage事件并触发setItem是不会生效的。
    • 符合同源策略,在同一浏览器下的不同窗口, 当焦点页以外的其他页面导致数据变化时,如果焦点页监听storage事件,那么该事件会触发
    • 换一种说法就是除了改变数据的当前页不会响应外,其他窗口都会响应该事件。

MessageChannel

MessageChannel API可以让运行在不同浏览器上下文中的独立脚本,连接到同一份文档(比如:两个 IFrame, 或者主文档和一个 IFrame, 或者使用同一个 SharedWorker 的两份文档),并直接通信,通过每端一个 port 的双向频道(或管道)在两者之间传递消息。

语法

更多内容看这里:传送门

案例

  1. const { port1, port2 } = new MessageChannel();
  2. port1.onmessage = function (d) {
  3. console.log(`port1接收的消息是:${d.data}`);
  4. };
  5. port2.onmessage = function (d) {
  6. console.log(`port2接收的消息是:${d.data}`);
  7. };
  8. // 发送消息
  9. console.log(port1, port2);
  10. port1.postMessage('port1发送的消息');
  11. port2.postMessage('port2发送的消息');
  12. port2.postMessage('port2发送的消息');

MessageChannel创建了一个通信的管道,这个管道有两个端口,每个端口都可以通过postMessage发送数据,而一个端口只要绑定了onmessage回调方法,就可以接收从另一个端口传过来的数据。

兼容性

image.png

注意事项

  1. 可以通过SharedWorker实现跨域通信,可是SharedWorker的兼容性堪忧。

SharedWorker

语法

更多内容看这里:传送门

案例

待完善

兼容性

image.png

注意事项

  1. 虽然功能强大,但兼容性堪忧。

WebSocket

所有的WebSocket都监听同一个服务器地址,利用send发送消息,利用onmessage获取消息的变化,不仅能窗口,还能跨浏览器,兼容性最佳,只是需要消耗点服务器资源。

语法

更多内容看这里:传送门

案例

  1. var ws = new WebSocket("ws://localhost:3000/")
  2. ws.onopen = function (event) {
  3. // 或者把此方法注册到其他事件中,即可与其他服务器通信
  4. ws.send({now : Date.now()}); // 通过服务器中转消息
  5. };
  6. ws.onmessage = function (event) {
  7. // 消费消息
  8. console.log(event.data);
  9. }

兼容性

image.png

注意事项

  1. 需要起一个后端服务做桥梁

参考文章

postMessage相关

BroadcastChannel相关

localStorage相关

MessageChannel相关

SharedWorker相关

WebSocket相关