【js学习笔记-116】-----html5之跨域消息传递

来源:互联网 发布:java培训机构学费 编辑:程序博客网 时间:2024/06/07 12:43

html5之跨域消息传递

一些浏览器窗口和标签之间都是完全相互独立的,在其中一个窗口或者标签中运行的代码在其他窗口或标签中完全无法识别。但是,在其他的一些场景下,当脚本显式打开一个新窗口或者在嵌套的窗体中运行的时候,多个窗口或者窗体之间是互相可识别的。如果它们包含的文档是来自同一台web服务器,则再这些窗口和窗体中的脚本可以互相之间进行交互和操作对方的文档。然而,有时候,尽管脚本可能引用其他的window对象,但是由于那个窗口中的内容是来自不同源,web浏览器不会允许访问其他窗口中的文档内容。大部分情况下,浏览器还不允许脚本读取其它窗口的属性或调用其它窗口的方法。不过有个window方法,是允许来自非同源脚本调用的postMessage()方法。该方法允许有限的通信,通过异步消息传递的方式在来自不同源的脚本之间。这类通信机制是html5标准中定义的,所有主流的浏览器都已经实现了该通信机制。这项技术称为“跨文档消息传递”,而由于该api是定义在window对象上的,而不是文档对象上的,因此,它又称为“窗口间消息传递”或者跨域消息传递

postMessage()方法接受两个参数。其中第一个参数是要传递是要传递的消息html5标准提到,该参数可能是任意基本类型值或者可复制的对象。但,有些当前浏览器的实现只支持字符串,因此,如果想要作为消息传递对象或者数组,首先应当使用JSON.stringify()方法对其序列化。第二个参数是一个字符串,指定目标窗口的源。其中包括协议、主机名以及URL(可选)端口部分。(可以传递一个完整的URL,但除了协议、主机名和端口号之外的任何信息都会忽略)。这是一个安全特性:由于恶意代码或普通用户都可以在窗口中浏览新的未知文档,因此postMessage()只会将消息传递给指定窗口,而不会传递给包含非同源文档的窗口。当然,如果传递的消息不包含任何敏感信息的话,并且愿意将其传递给任何窗口,就可以直接将参数设置成”*”通配符即可。如果要指定和当前窗口同源的话,那么也可以简单地使用”/”.

如果指定的源匹配的话,那么当调用postMessage()方法的时候,在目标窗口的Window对象上就会触发一个message事件。在目标窗口中的脚本则可以通知message事件处理程序函数。调用该事件处理程序的时候会传递给它一个拥有如下属性的事件对象:

data

     作为一个参数传递给postMessage()方法的消息内容副本

source

      消息源自的window对象

origin

       一个字符串,指定消息来源(URL形式)

通常,onmessage()事件处理程序应当首先检测其中的origin属性,忽略来自未知源的消息。

当想要在Web页面中嵌入一个来自其他站点的模块或者“gadget”的时候,利用postMessage()message事件实现的跨域消息传递是很有用的。当然,如果gadget本身就很简单并且是自包含的,就可以直接简简单地将它放在iframe中实现隔离即可。

然而,假设gadget本身比较复杂,它自身还定义了一些API,同时web页面需要利用

这些API和它进行交互。这个时候,用<iframe>就不行了,而如果将它嵌入在<script>元素中,它可以提供一个正常的js API,但同时它也可以完全操控页面和页面的内容了。目前在web上通常不会这样去做,哪怕信任第三方站点,这也不是个好方案。

(经测试在IE(真TMD相骂娘,这么烂的东西,还活这么久!)新开tab页面下的postMessage没反应-----IE8~10都是这样的)

摘网友写提的:

  当然,仅 IE Mobile是部分支持。见http://caniuse.com/#feat=x-doc-messaging

旧版本的 IE<=10)都没有完全支持。浏览器壳的话自己看用的什么内核吧。

还有这个哥们postMessageonly works for IFRAMES/FRAMES  

Update: As of IE11, this issue has notyet been fixed.

http://blogs.msdn.com/b/ieinternals/archive/2009/09/16/bugs-in-ie8-support-for-html5-postmessage-sessionstorage-and-localstorage.aspx

网上大部的实例都是基于iframe

跨域消息传递提供了别外一种实现方案:首先gadget的开发者可将gadget的内容定义在一个html页面中,它负责监听message事件,并将它们分发给对应的js函数去处理。然后,嵌入gadgetweb页面就可以通过postMessage()方法传递消息来和gadget进行交互了。下列就是一个简单的gadget,放置在<iframe>中,它搜索并将匹配指定搜索项的twweet显示出来。要让它实现真正搜索功能,包含的页面只需要简单地作为消息传递搜索项给它即可。

0 0
原创粉丝点击