本文主要探讨用于构建实时跨源通信的两个模块:跨文档消息通信(Cross Document Messaging)和XMLHttpRequestLevel2。通过这两个模块,我们可以构建不同域间进行安全通信的Web应用。
出于安全方面的看的考虑,运行在同一浏览器中的框架、标签页、窗口间的通信一直多受到严格的限制。但是现实中还存在一些合理的让不同站点的内容能在浏览器内进行交互的需求,其中Mashup就是一个典型的例子,它是各种不同应用的结合体。为了满足上述需求,引入了一种新的功能:跨文档消息通信。其可以确保iframe、标签页、窗口间安全地进行跨源通信。
发送消息使用postMessage API,其示例代码如下:
接受消息时,需要在页面中添加一个事件处理函数,当消息到达时,通过检查消息的来源来决定如何对这条消息如何处理,示例代码如下:postMessage API提供了一种交互方式,使得不同源的iframe之间可以进行消息通信。
HTML5 通过引入源的感念对域安全进行了阐明和改进。源是网络上用来建立信任关系的地址的子集。源由规则(scheme)、主机(host)、端口(port)组成,例如由于scheme(https、http)不同,则源不同。
跨源通信通过 源来确定发送者,这就使得接收方可以忽略或者拒绝来自不可信源的消息。同时需要通过添加监听事件来接受消息,以避免被不可信应用程序的信息所干扰。但是在使用外来消息时,即便是可靠的数据源,也同样要谨慎,以防止内容注入。
在使用postMessage API时,需要遵循以下步骤:
1、检查浏览器是否支持
2、发送消息
第一个参数包含要发送的数据,第二个参数时消息传递的目的地。
如果要发送消息给iframe,则使用如下代码:
1 | document.getElementById( "iframe" )[0].contentWindow.postMessage( "Hello" , "xx.example.com" ); |
XMLHttpRequestLevel2是XMLHttpRequest的改进版本,主要涉及:跨源XMLHttpRequess和进度事件(Progress events)。
XMLHttpRequest仅限于同源通信,XMLHttpRequestLevel2通过跨资源共享实现(Cross Origin Resource Sharing)跨源XMLHttpRequests。
在XMLHttpRequest中通过readystatechange事件来响应进度,但是其在某些浏览器中不被兼容。XMLHttpRequestLevel2用了一个有意义的名字Progress进度来命名进度事件。其进度事件的名称主要有loadstart、progress、abort、error、load、loadend。通过对程序属性设置回调函数,可以实现对这些事件的监听。
在使用XMLHttpRequestLevel2时,需要遵循以下步骤:
1、检查浏览器是否支持
2、构建跨源请求
1 2 | var crossOriginRequest = new XMLHttpRequest(); |
在请求过程中,务必确保能够监听到错误,以找出出错原因,解决问题。
3、使用进度事件
以跨源聊天应用为例,来演示门户页面和聊天部件之间的交互。
1、创建postMessagePortal.html页面
2、创建postMessageWidget.html
注意:第一、上述的两个页面需要部署到web服务器;第二、两个页面必须来自不同的域。如果要在本机部署,则需要更改hosts文件,增加:
这是因为访问一页面的域与所请求的域非同源造成的。且浏览器是根据响应头的规则来确定这个域是否同源可以接收。
因此我们需要http://geodata.example.net:8080/upload在返回内容时,设置Header Access-Control-Allow-Origin,即:
Response.AddHeader("Access-Control-Allow-Origin","*") ;
浏览器在接收到服务器返回信息时,会检查响应头的Access-Control-Allow-Origin,它的值标识请求内容所允许的域。如果将服务器设置Access-Control-Allow-Origin为*,表明该返回信息允许所有源访问。如果设置为具体的域,如http://xx.com,就表明除了同源外,只允许域来自xx.com的访问。