跨文档消息传送(cross-document messaging),有时候也简称为XDM,指的是来自不同域的页面间传递消息。例如,www.w3cmm.com域中的一个页面与一个位于内嵌框架中的p2p.w3cmm.com域中的页面通信。在XDM机制出现之前,更稳妥地实现这种通信需要花很多功夫。XDM把这种机制规范化,让我们能既稳妥有简单地实现跨文档通信。

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

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

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

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

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

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

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

var EventUtil = {
    addHandler: function (element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    }
}; EventUtil.addHandler(window, "message", function (event) {
    //确保发送消息的域是已知的域
    if (event.origin == "http://www.w3cmm.com") {
        //处理接收到的数据
        processMessage(event.data);
        //可选:向来源窗口发送回执
        event.source.postMessage("Received!", "http://p2p.w3cmm.com");
    }
});

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

XDM还有一些怪异之处。首先,postMessage()第一个参数最早是作为“永远都是字符串”来实现的。但后来这个参数的定义改了,改成允许传入任何数据结构。可是,并非所有浏览器都实现了这一变化。为保险起见,使用postMessage()时,最好还是只传字符串。如果你想传入结构化的数据,最佳选择是先在要传入的数据上调用JSON.stringify(),通过postMessage()传入得到的字符串,然后再在onmessage事件处理程序中调用JSON.parse()。

在通过内嵌框架加载其它域的内容时,使用XDM是非常方面的。因此,在混搭和社交网络应用中,这种传递消息的方法极为常用。有了XDM,包含<iframe>的页面可以确保自身不受恶意内容的侵扰,因为它只通过XDM为嵌入的框架通信。而XDM也可以来自相同域的页面间使用。

Related posts:

  1. HTML5中的拖放

HTML5中的跨文档消息传递的更多相关文章

  1. HTML5跨文档消息传递

    HTML5定义了一些javascript API,其中有一个就是跨文档消息传递(cross-document-messaging简称XDM). 现在XDM已经作为一个规范独立了出来,名字为:Web M ...

  2. HTML5实战与剖析之跨文档消息传递(iframe传递信息)

    在来自不同域名的页面间传递消息一般统称为跨文档消息传送,简称XDM.如,www.leemagnum.com域中的页面与位于一个内嵌框架中的http://blog.csdn.net/lee_magnum ...

  3. 跨文档消息传递----postMessage()

    HTML5 规范中,提出了XDM,又称为 跨文档消息传递,其核心是 postMessage()方法,进行跨域和跨文档消息传递,示例如下: <div class="CrossDocume ...

  4. HTML(六)HTML iframe 使用postMessage方法进行跨文档消息传递

    什么是iframe HTML内联框架元素 <iframe> 表示嵌套的浏览上下文,有效地将另一个HTML页面嵌入到当前页面中. <iframe id="inlineFram ...

  5. HTML5学习之跨文档传输消息(七)

    新标准中提供了文档之间直接的消息传输API.而且不限制跨域消息传递! 发送消息使用的是Window对象的postMessage(data,targetURL)方法就可以了,但给哪个window对象发送 ...

  6. 通过Html5的postMessage和onMessage方法实现跨域跨文档请求访问

    在项目中有应用到不同的子项目,通过不同的二级域名实现相互调用功能.其中一个功能是将播放器作为单独的二级域名的请求接口,其他项目必须根据该二级域名调用播放器.最近需要实现视频播放完毕后的事件触发,调用父 ...

  7. HTML5 跨文档消息传输

    对窗口对象的message事件进行监听 window.addEventListener("message", function(event) { // 处理程序代码 }, fals ...

  8. 如何在程序中给word文档加上标和下标

    如何在程序中给word文档加上标和下标 上标或下标是一个小于普通行格式的数字,图形,标志或者指示通常它的设置与行相比偏上或偏下.下标通常显示于或者低于基准线,而上标则高于.上标和下标通常被用于表达公式 ...

  9. C# 中使用Word文档对图像进行操作

    C# 中使用Word文档对图像进行操作 Download Files: ImageOperationsInWord.zip 简介 在这篇文章中我们可以学到在C#程序中使用一个Word文档对图像的各种操 ...

随机推荐

  1. Replication容量和错误日志

    gtid排错 set sql_log_bin=off;  #人为关闭二进制日志

  2. 消息监听器无法注入bean

    问题描述: 在activemq的监听器中,通过注解@Autowired或@Resource注入bean时,获取到的bean为null.调用该bean的方法时会报空指针异常. 问题原因: 当调用bean ...

  3. 解决创建maven项目Could not resolve archetype org.apache.maven.archetypes:maven-archetype-quickstart问题

    今天用eclipse创建项目的时候报错如下图: 解决方案: 1.下载最新版maven-archetype-quickstart-1.1.jar   2.命令行到下载目录下执行mvn install:i ...

  4. 由time.tzname返回值引发的对str、bytes转换时编码问题实践

    Windows 10家庭中文版,Python 3.6.4, 下午复习了一下time模块,熟悉一下其中的各种时间格式的转换:时间戳浮点数.struct_tm.字符串,还算顺利. 可是,测试其中的time ...

  5. 使用android模拟器开发程序

    自从android studio升级到3.0之后自带的模拟器已经很好用了,尤其是升级后可以想vmware那样休眠,再次开启就可以快速启动了 以下是几点可以更方便地使用系统模拟器进行开发的小技巧,毕竟模 ...

  6. spring各个版本源码

    各版本源码下载地址 http://maven.springframework.org/release/org/springframework/spring/

  7. 洛谷P3375KMP字符串匹配

    传送门 #include <iostream> #include <cstdio> #include <cstring> #include <algorith ...

  8. PHP中curl模拟post上传及接收文件

    public function Action_Upload(){ $this->path_config(); exit(); $furl="@d:\develop\JMFramewor ...

  9. Java编程的逻辑 (10) - 强大的循环

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  10. Web Automation with Selenium (C#)

    Web Automation is a quite regular task nowadays, scripting for repeated operations and testing. Sele ...