主页面main.htmlhtml
<!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>
加载iframe页面,sub.htmlwindows
<!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>
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() 方法的窗口信息。app
postMessage语法
otherWindow.postMessage(message, targetOrigin, [transfer]);
targetOrigin:经过窗口的origin属性来指定哪些窗口能接收到消息事件,其值能够是字符串"*"(表示无限制)或者一个URI。在发送消息的时候,若是目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;
transfer:
可选是一串和message 同时传递的 Transferable
对象. 这些对象的全部权将被转移给消息的接收方,而发送一方将再也不保有全部权。框架
Channel Messaging API容许两个独立的脚本在不一样的浏览环境(浏览上下文)中链接到同一个文档(例如两个iframes框架或主文档和一个iframe框架,或两个文档经过SharedWorker
一个共享工做线程或 两个线程)进行直接通讯,经过两端各有一个端口port的双向通道channel(或管道)来传递消息。dom
使用MessageChannel()
构造器建立消息通道。一旦建立,管道的两个端口能够经过MessageChannel.port1
和MessageChannel.port2
属性来访问。建立该通道的应用app使用port1,而应用app端口的另外一端使用port2,你发送一个消息到port2,使用window.postMessage和两个参数(要发送的消息,以及传输全部权对象,本例中指端口自己)将端口转移到另外一个浏览上下文。ide
当这些可传输的对象被转移时,它们在以前的上下文中被“停止”—它们以前所属的上下文。例如,一个端口在发送时不能被原始上下文使用。注意,目前只能传输ArrayBuffer
和MessagePort
对象。post
其余浏览上下文可使用 MessagePort.onmessage
来监听消息,并使用事件的data属性来获取消息内容。而后您可使用MessagePort.postMessage
将消息发送回原始文档。this
当你想中止发送消息时,能够调用MessagePort.close
来关闭端口。spa
Channel messaging interfaces/消息通道接口
建立一个新的消息通道来发送消息。
控制消息通道上的端口,容许从一个端口发送消息,并侦听到达另外一个端口的消息。
一组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