MessageChannel消息通道--笔记

 主页面main.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form>
<input type='text' id='sr'>
<button type='button' id='submit'>提交</button>
</form>
<div id='message'></div>
<iframe src='./msgIframe.html'></iframe>
<script>
//通道通信
var port;
var ifr = document.querySelector('iframe');
var eleBox = document.querySelector("#message");


var submit = document.querySelector("#submit");
submit.onclick=function(){
    var srinput = document.querySelector("#sr");
    
    //window.frames[0].postMessage(srinput.value, '*');
    
    port.postMessage(srinput.value);//iframe加载后向本页面父窗口发送消息,从e中获取通道端口信息,然后可以通过此port向iframe窗口中发送消息
}

window.addEventListener("message", function(e){
     eleBox.innerHTML = '接受到的信息是:' + e.data;
     if(e.ports){
         port=e.ports[0];
     }
}, false);

//跨文档通信
/*var eleBox = document.querySelector("#message");

var submit = document.querySelector("#submit");
submit.onclick=function(){
    var srinput = document.querySelector("#sr");
    
    postMessage(srinput.value, '*');
}

window.addEventListener("message", function(e){
     eleBox.innerHTML = '接受到的信息是:' + e.data;
}, false);*/

</script>
</body>
</html>
View Code

加载iframe页面,sub.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div id='message'></div>

<script>
var port;
var eleBox = document.querySelector("#message");
var channel = new MessageChannel();
window.addEventListener('DOMContentLoaded', function(e) {
    //向父窗口发送消息,
    window.parent.postMessage('发送页加载完毕', '*',[channel.port2]);
  /*   channel.port1.addEventListener('message', function(e){
        eleBox.innerHTML='通道获取的消息为:'+e.data;
    }, false); */
    channel.port1.onmessage(function(e){
        eleBox.innerHTML='通道获取的消息为:'+e.data;
    })
    channel.port1.start();
    
} ,false);

</script>
</body>
</html>
View Code

window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机  (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。

window.postMessage() 方法被调用时,会在所有页面脚本执行完毕之后(e.g., 在该方法之后设置的事件、之前设置的timeout 事件,etc.)向目标窗口派发一个  MessageEvent 消息。 该MessageEvent消息有四个属性需要注意: message 属性表示该message 的类型; data 属性为 window.postMessage 的第一个参数;origin 属性表示调用window.postMessage() 方法时调用页面的当前状态; source 属性记录调用 window.postMessage() 方法的窗口信息。

postMessage语法
otherWindow.postMessage(message, targetOrigin, [transfer]);
targetOrigin:通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;

transfer: 可选是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。

Channel Messaging API允许两个独立的脚本在不同的浏览环境(浏览上下文)中连接到同一个文档(例如两个iframes框架或主文档和一个iframe框架,或两个文档通过SharedWorker一个共享工作线程或 两个线程)进行直接通信,通过两端各有一个端口port的双向通道channel(或管道)来传递消息。

通道消息概念和使用

使用MessageChannel()构造器创建消息通道。一旦创建,管道的两个端口可以通过MessageChannel.port1 和MessageChannel.port2 属性来访问。创建该通道的应用app使用port1,而应用app端口的另一端使用port2,你发送一个消息到port2,使用window.postMessage和两个参数(要发送的消息,以及传输所有权对象,本例中指端口本身)将端口转移到另一个浏览上下文。

当这些可传输的对象被转移时,它们在之前的上下文中被“中止”—它们之前所属的上下文。例如,一个端口在发送时不能被原始上下文使用。注意,目前只能传输ArrayBuffer 和MessagePort对象。

其他浏览上下文可以使用 MessagePort.onmessage来监听消息,并使用事件的data属性来获取消息内容。然后您可以使用MessagePort.postMessage将消息发送回原始文档。

当你想停止发送消息时,可以调用MessagePort.close 来关闭端口。

Channel messaging interfaces/消息通道接口

MessageChannel

创建一个新的消息通道来发送消息。

MessagePort

控制消息通道上的端口,允许从一个端口发送消息,并侦听到达另一个端口的消息。

PortCollection

一组MessagePorts; 一个允许同时向多个端口广播消息的实验性解决方案。

参考:

https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API

原文地址:https://www.cnblogs.com/xiaozhuyuan/p/8419749.html