postMessage 是 HTML5 新方法,它可以实现跨域窗口之间通讯。到目前为止,只有 IE8+, Firefox 3, Opera 9, Chrome 3和 Safari 4 支持,而本篇文章主要讲述 postMessage 方法与 message 事件跨浏览器实现。
postMessage 方法 JSONP 技术不一样,前者是前端擅长跨域文档数据即时通讯,后者擅长针对跨域服务端数据通讯,postMessage 应用场景能说明这个区别:
应用场景举例
-
webOS 使用 iframe 嵌入第三方应用,此时 webOS 与应用需要实时接收/发送各自的消息与响应事件。
-
页面弹出一个由 iframe 层,嵌入第三方提供的图片上传页面,文件上传完毕后需要获取返回图片地址插入到编辑器。
-
iframe 跨域高度自适应。可以500%提高开发效率的前端UI框架!
HTML5 postMessage 方法
postMessage 可以实现跨域文档的消息传输(Cross Document Messaging)。
向外界窗口发送消息:
otherWindow.postMessage(message, targetOrigin);
otherWindow: 指目标窗口,是 window.frames 属性的成员或者由 window.open 方法创建的窗口
参数说明:
-
message:是要发送的消息,类型为 String、Object (IE8、9 不支持)
-
targetOrigin:是限定消息接收范围,不限制请使用 ‘*’
HTML5 message 事件
绑定消息事件:
window.addEventListener('message', receiver, false); function receiver (event) { if (event.origin === 'http://example.com') { if (event.data === 'Hello world') { event.source.postMessage('Hello', event.origin); } else { alert(event.data); }; }; };
调函数第一个参数接收 Event 对象,有三个常用属性:
-
data:消息
-
origin:消息来源地址
-
source:源 DOMWindow 对象可以500%提高开发效率的前端UI框架!
message 事件在低版本浏览器下模拟实现
对于支持 postMessage 方法的浏览器直接使用它;而对于 IE6、7 采用了比较成熟的 window.name 保存数据以及跨域 iframe 静态代理动态传输方案,下面简称 Cross Frame。
Cross Frame
假设在域 www.a.com 上有页面 a.html 和代理页面 proxy-a.html , 另一个域 www.b.com 上有个页面 b.html 和代理页面 proxy-b.html,a.html 需要向 b.html 中发送消息时,页面会创建一个隐藏的 iframe 指向 proxy-b.html ,并把消息赋予 iframe.name 属性,此时 proxy-b.html 可以通过 window.name 获取到消息,由于 proxy-b.html 与 b.html 是同域,proxy-b.html 可以把消息赋予 b.html。 b.html 要给 a.html 发送消息时,原理一样。
自动捕获代理 URL
在 Cross Frame 方案中,通信双方必须确切的知道静态代理文件的 URL,显然这个极大的限制了应用范围,我们可以通过一些约定改善:静态代理文件必须置于通信页面所在域根目录,且文件名必须保持一致,如 messageEvent-proxy.html。
有了上述约定,接下来可以用一些巧妙的方法让双方自动捕获代理 URL。以 http://www.a.com/a.html 通过 iframe 嵌入 http://www.b.com/b.html 保持数据交换为例进行说明:
b.html 的静态代理路径可以通过正则分析 iframe.src 后得知;而从框架 b.html 内获取父页面就比较麻烦了,因为跨域后的 parent.location.href 属性只可写入不可读取,不过还可以借用 document.referrer 属性来分析来路地址得知父页面 url。document.referrer 是一个不稳定的属性,我们可以利用 iframe 中 window.name 刷新也不会变化的特性,用此来保存父页面 a.html 的地址。
持续跟踪 URL可以500%提高开发效率的前端UI框架!
a.html 第一次通过提取 iframe.src 路径可得知 b.html 的地址,假若 b.html 跳转到其他域名的时候,此时就会失去对 iframe 内静态代理的联络。 好在新页面由于能够获取父页面 a.html 保存在 window.name 的静态代理,所以我们可以在新页面初始化的时候向 a.html 传递消息告诉它新的地址,这样就能持续跟踪 iframe 中的 URL。
开源事件库 messageEvent.js
“messageEvent.js”是针对上述方案封装的 message 事件与 postMessage 方法库,它让各个浏览器之间 message 的 Event 对象成员属性统一,event.data 属性能传递多达 2MB 的文本信息,并且能让 IE6-9 浏览器像其他现代浏览一样支持 Object 类型数据进行传递 (内部使用深拷贝方式)。
若应用双方页面都采用 messageEvent.js,即可轻松实现跨域通信。
接口
-
add(callback)添加 message 事件
-
remove(callback)卸载 message 事件
-
postMessage(otherWindow, message, targetOrigin)向外部窗口发送消息
通过 jQuery 使用它
jQuery 是一个应用比较广泛的 DOM 库,它的事件机制非常强大而精妙,可以实现自定义事件。若页面引用了 jQuery, messageEvent.js 会为为它提供支持,你可以用熟悉的jQuery api 风格编程,如: 可以500%提高开发效率的前端UI框架!
jQuery(window).bind('message', function (event) { alert(event.data) }); jQuery(window).message(function (event) { alert(event.data) }); jQuery.postMessage(iframe.contentWindow, 'hello world', '*'); jQuery(window).unbind('message');
由于 jQuery 把包装后的 Event 对象用 data 属性来保存 bind 方法传入的额外数据,导致与 message 事件自身的 event.data 属性冲突——这是一个设计错误。为了让 message 事件能够正确获取 event.data,messageEvent.js 通过操作 jQuery 底层缓存强制覆盖了 bind 方法传入的附加数据 (只针对 message 类型)。当然,我仍然期待 jQuery 未来版本能够取消掉 bind 方法的鸡肋特性。
相关推荐
PostMessage 后台模拟按键 MOUSE VC原码 PostMessage 后台模拟按键 MOUSE VC原码 可以后台操作的,模拟按键,VC 代码.
在做 React Native 应用时,如果需要在 App 里面内嵌 H5 页面,那么 H5 与 App 之间可以通过 Webview 的 PostMessage 功能实现实时的通讯,但是在小程序里面,虽然也提供了一个 webview 组件,但是,在进行 post...
POSTMESSAGE后台模拟按键源码,可以POSTMESSAGE按键消息到其他程序中
html5 API postMessage 实现消息跨域推送
估计很少人知道HTML5 APIS里有一个window.postMessage API。window.postMessage的功能是允许程序员跨域在两个窗口/frames间发送数据信息。基本上,它就像是跨域的AJAX,但不是浏览器跟服务器之间交互,而是在两个...
VC 利用postmessage和keybd_event给其他程序发送消息,能成功发送CTRL/SHIFT/ALT键
html5 postMessage解决跨域、跨窗口消息传递 这也是html5另一个API——web workers传递消息的方法
练习说明:使用postMessage可以在iFrame、父子窗口、跨页面等,之间相互传递消息。 你好,我是TKCB-GO,一个有着游戏策划梦想,却沦为程序员的游戏家,这是我的技术博客:www.tkcb.cc 技术博客网站里面,除了我的...
HTML5 postMessage+iframe实现文件跨域异步上传 http://blog.csdn.net/jiangsyace/article/details/43858443
js中窗口的postMessage方法1
主要示例在C#中的SendMessage,PostMessage,包含两个示例,一个资料文档,希望受用。 在C#中 API 消息处理 SendMessage PostMessage 进程通信 发消息 实例 文档资料
NULL 博文链接:https://tiger-passion.iteye.com/blog/1111395
在C#中SendMessage和PostMessage的参数传递 在C#中可以使用Window API提供的SendMessage和PostMessage来传递参数。两者的区别简单介绍下:返回值的不同,我们先看一下 MSDN 里的声明: LRESULT SendMessage( HWND ...
资源包含两个源程序,里面是借用MFC的消息通信实现简单的两个进程间通信,嗯主要是通过SendMessage或PostMessage,功能实现简单便捷。
postmessage解析HTML5提供了新型机制PostMessage实现安全的跨源通信. 语法 otherWindow.postMessage(message, targetOrigin, [transfer]); otherWindow: 其他窗口的一个引用, 比如IFRAME的contentWindow属性, 执行,...
NULL 博文链接:https://weistar.iteye.com/blog/1845314
html5 API postMessage跨域详解.pdf
iframe+postMessage实现跨域通信 window.postMessage()方法安全地启用Window对象之间的跨源通信;例如,在页面和它产生的弹出窗口之间,或者在页面和嵌入其中的iframe之间。
后台利用PostMessage发送消息拖动绑定窗口中的可移动小窗口交流群QQ:974351321
易语言PostMessage源码,PostMessage