MessageChannel

定义: Channel Messaging API允许两个不同的脚本运行在同一个文档的不同浏览器上下文(比如两个 iframe)。
使用MessageChannel()构造函数来创建通讯信道。一旦创建,信道的两个端口即可通过MessageChannel.port1MessageChannel.port2属性进行访问(都会返回MessagePort 对象)。创建信道的应用程序使用 port1,在另一端的程序使用 port2 —— 你向 port2 发送信息,然后携带 2 个参数(需要传递的消息,要传递所有权的对象,在这里是 port 自身)调用 window.postMessage方法将端口信息传递到另一个浏览器上下文。
当这些可传递的对象被传递后,他们就从之前所属的上下文中消失了。比如一个 port,一旦被发送,在原本的上下文中就再也不可用了。注意当前仅有 ArrayBufferMessagePort对象可以被发送。
另一个浏览器上下文可以使用 MessagePort.onmessage监听信息,并使用事件的 data 属性获取消息内容。你可以通过 MessagePort.postMessage(en-US)向原来的文档发送应答消息。
当你想要停止通过信道发送消息时,你可以调用来关闭MessagePort.close(en-US)端口。
更多使用这个 API 的资料参见:Using channel messaging

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6. <meta name="viewport" content="width=device-width">
  7. <title>Channel messaging demo</title>
  8. <link rel="stylesheet" href="">
  9. <!--[if lt IE 9]>
  10. <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  11. <![endif]-->
  12. </head>
  13. <body>
  14. <h1>Channel messaging demo</h1>
  15. <p class="output">My body</p>
  16. <iframe src="page2.html" width='480' height='320'></iframe>
  17. </body>
  18. <script>
  19. var channel = new MessageChannel();
  20. var output = document.querySelector('.output');
  21. var iframe = document.querySelector('iframe');
  22. // Wait for the iframe to load
  23. iframe.addEventListener("load", onLoad);
  24. function onLoad() {
  25. // Listen for messages on port1
  26. channel.port1.onmessage = onMessage;
  27. // Transfer port2 to the iframe
  28. // 第三个参数是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
  29. iframe.contentWindow.postMessage('Hello from the main page!', '*', [channel.port2]);
  30. }
  31. // Handle messages received on port1
  32. function onMessage(e) {
  33. output.innerHTML = e.data;
  34. }
  35. </script>
  36. </html>

page2.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6. <meta name="viewport" content="width=device-width">
  7. <title>My page title</title>
  8. <link rel="stylesheet" href="">
  9. <!--[if lt IE 9]>
  10. <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  11. <![endif]-->
  12. </head>
  13. <body>
  14. <p class="output">iFrame body</p>
  15. </body>
  16. <script>
  17. var output = document.querySelector('.output');
  18. window.addEventListener('message', onMessage);
  19. function onMessage(e) {
  20. output.innerHTML = e.data;
  21. // Use the transfered port to post a message back to the main frame
  22. // MessageEvent.ports 表示消息正通过特定通道(数据通道)发送的相关端口 下解释
  23. // 经过试验这里的e是MouseEvent实例。
  24. e.ports[0].postMessage('Message back from the IFrame');
  25. }
  26. </script>
  27. </html>

补充概念

window.postMessage()方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage()方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。
从广义上讲,一个窗口可以获得对另一个窗口的引用(比如targetWindow = window.opener),然后在窗口上调用targetWindow.postMessage() 方法分发一个 MessageEvent消息。接收消息的窗口可以根据需要自由处理此事件。传递给 window.postMessage() 的参数(比如 message )将通过消息事件对象暴露给接收消息的窗口


MessageEvent MessageEvent 是接口代表一段被目标对象接收的消息。
用来代表下列情况的消息 :
Server-sent events (参见EventSource.onmessage (en-US)).
Web sockets (参见 WebSocket 接口的 onmessage 属性).
Cross-document messaging (参见 Window.postMessage() 和 Window.onmessage).
Channel messaging (参见 MessagePort.postMessage() (en-US) 和MessagePort.onmessage).
Cross-worker/document messaging (参见上面两个入口, 还有 Worker.postMessage(), Worker.onmessage, ServiceWorkerGlobalScope.onmessage (en-US), 等等.)
Broadcast channels (参见 Broadcastchannel.postMessage()) 和 BroadcastChannel.onmessage).
WebRTC data channels (参见 RTCDataChannel.onmessage (en-US)).
通过这个事件触发的动作被定义为一个函数,该函数作为相关message事件 (例如使用前文所列的onmessage 处理器)的事件处理器。
特有
MessageEvent.data (en-US) 只读
返回 DOMString, Blob 或者 ArrayBuffer,包含来自发送者的数据。
MessageEvent.origin (en-US)
返回一个表示消息发送者来源的USVString
MessageEvent.lastEventId (en-US) 只读
DOMString representing a unique ID for the event.
MessageEvent.source (en-US)
MessageEventSource (可以是 WindowProxy, MessagePort, 或 ServiceWorker 对象) 代表消息发送者.
MessageEvent.ports (en-US)
MessagePort对象数组,表示消息正通过特定通道(数据通道)发送的相关端口(适用于通道消息传输或者向一个共享线程(shared work )发送消息时)。