美文网首页
iframe如何跨框架通信?跨文档消息传递?

iframe如何跨框架通信?跨文档消息传递?

作者: 宋乐怡 | 来源:发表于2019-08-29 17:04 被阅读0次

跨文档消息传递(cross-document-messaging)CDM,指的是在来自不同域的页面间传递消息。

XMD的核心是postMessage()方法。在H5中,除了XMD部分之外的其他部分也会提到这个方法,但都是为了同一个目的:向另一个地方传递数据。对于XMD而言,“另一个地方”指的是包含在当前页面的<iframe>元素,或者由当前页面弹出的窗口。

postMessage()接受两个参数:一条消息和一个表示消息接收方来自哪个域的字符串(目的地)。第二个参数对保证安全通信非常重要,可以防止浏览器把消息发送到不安全的地方。

所有支持XMD的浏览器都支持iframe的contentWindow属性

var iframeWidow = document.getElementById("myframe").contentWindow;
iframeWindow.postMessage("A secret","http://www.wrox.com");

最后一行代码尝试向内嵌框架中发送一条消息,并指定框架中的文档必须来源于"http://www.abc.com"域。如果来源匹配,消息会传递到框架中,否则,postMessage()什么也不做。这一限制可以避免窗口中的位置在你不知道的情况下发生改变。如果传递给postMessage()的第二个参数是'*',则表示可以把消息发送给来自任何域的文档,但是我们不推荐这种做法。

收到XDM消息时,会触发window对象的message事件。这个事件是以异步形式触发的,因此从发送消息到接收消息(触发接受窗口的message事件)可能要经过一段时间的延迟。触发message事件后,传递给onmessage处理程序的事件对象包含以下三方面的重要信息:

  • data:作为postMessage()第一个参数传入的字符串数据。
  • origin:发送消息的文档所在的域,例如"http://www.wrox.com"
  • source:发送消息的文档的window对象的代理。这个代理对象主要用于在发送上一条消息的窗口中调用postMessage()方法。如果发送消息的窗口和接受消息的窗口来自同一个域,那这个对象就是window。

接收到消息后,验证发送窗口的来源是非常重要的。就像给postMessage()方法执行第二个参数,以确保浏览器不会把消息发送给未知的页面一样,在onmessage处理程序中检测消息来源可以确保传入的消息来自已知的页面
基本的检测模式如下:

EventUtil.addHandler(window,"message",function(event){
// 确保发送消息的域是已知的域
if(event.origin == "http://www.wrox.com");
//处理接收到的数据
processMessage(event.data);
//可选,向来源窗口发送回执
event.source.postMessage("Recieved","http://p2p.poster.com");
})

还要提醒大家,event.source大多数情况下只是window对象的代理,并非实际的window对象,换句话说,不能通过这个代理对象访问window对象的其他任何信息。记住,只通过这个代理调用postMessage()就好,这个方法永远存在,永远可以调用。

XDM还有一些怪异之处。
使用postMessage()时,最好还是只传字符串。如果想传入结构化的数据,最佳选择是先在要传入的数据上调用JSON.stringify(),通过postMessage()传入得到的字符串,然后再在onmessage时间处理程序中调用JSON.parse()。

通过内嵌框架加载其他域的内容时,使用XDM是非常方便的。有了XDM包含<iframe>的页面可以确保自身不受恶意内容的侵扰,因为它只通过XDM与嵌入的框架通信。而XDM也可以在来自相同域的页面间使用。

支持XDM的浏览器有IE8+、FireFox3.5+、Safari4+、Opera、Chrome、iOS版Safari及Andriod版Webkit。XDM已经作为一个规范独立出来,现在他的名字叫 Web Messaging。

相关文章

网友评论

      本文标题:iframe如何跨框架通信?跨文档消息传递?

      本文链接:https://www.haomeiwen.com/subject/dcxwectx.html