`

跨浏览器 HTML5 postMessage 方法以及 message 事件模拟实现

阅读更多

postMessage 是 HTML5 新方法,它可以实现跨域窗口之间通讯。到目前为止,只有 IE8+, Firefox 3, Opera 9, Chrome 3和 Safari 4 支持,而本篇文章主要讲述 postMessage 方法与 message 事件跨浏览器实现。

postMessage 方法 JSONP 技术不一样,前者是前端擅长跨域文档数据即时通讯,后者擅长针对跨域服务端数据通讯,postMessage 应用场景能说明这个区别:

应用场景举例

  1. webOS 使用 iframe 嵌入第三方应用,此时 webOS 与应用需要实时接收/发送各自的消息与响应事件。

  2. 页面弹出一个由 iframe 层,嵌入第三方提供的图片上传页面,文件上传完毕后需要获取返回图片地址插入到编辑器。

  3. 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 对象,有三个常用属性:

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 方法的鸡肋特性。

0
0
分享到:
评论

相关推荐

    c#模拟浏览器请求

    本文将深入探讨如何使用C#编写控制台程序来模拟浏览器发送HTTP请求,以及实现请求流程的自动化。 首先,我们需要了解HTTP请求的基本结构。一个标准的HTTP请求由以下部分组成:请求行(包括请求方法、URL和HTTP版本...

    chrome 浏览器跨域插件下载

    4. POSTMessage:一种在不同源之间进行通信的方式,通过`window.postMessage()`方法发送消息,监听`message`事件接收消息。 解决跨域问题的其他方法还包括使用代理服务器、设置CORS策略、JSONP、iframe等。在实际...

    html5 postMessage前端跨域并前端监听的方法示例

    HTML5的`postMessage` API是前端实现跨域通信的重要工具,它允许不同源的脚本采用异步方式进行有限的通信,打破了浏览器的同源策略限制。`postMessage`方法适用于处理如iframe、window.open创建的新窗口、或者通过...

    C_(WINFORM)实现模拟POST发送请求登录网站

    在本篇文章中,我们将探討如何使用C#模拟浏览器post发送请求实现自动登录网站的方法。通过阅读本文,您将了解到如何使用HttpWebRequest和HttpWebResponse类来发送POST请求,并获取服务器的响应结果。 首先,让我们...

    Java代码调用HTML5中的JS函数算法

    4. **HTML5的PostMessage API**:这是一种跨文档消息传递机制,允许不同源的窗口之间进行通信。Java服务器端可以生成一个包含调用信息的消息,然后由JavaScript监听并处理这个消息。 5. **HTML5的Web Storage**:...

    delphi WebBrowse模拟鼠标点击

    在Delphi中,我们可以使用PostMessage函数发送这些消息到WebBrowser控件,模拟鼠标按下和释放的动作。以下是基本的步骤: 1. 获取WebBrowser控件的句柄(Handle),这是发送消息的目标。 2. 使用GetCursorPos函数...

    如何从具有跨浏览器支持的网页启动窗口应用程序(.exe)

    通过配合使用`postMessage`API,Web应用可以与本地的Web套接字服务进行通信,从而触发.exe文件的启动。 4. **Electron框架**:Electron是一个流行的开源框架,它使用Node.js和Chromium构建跨平台的桌面应用。如果你...

    libxdr:一个实现跨浏览器XDR构造函数的库

    libxdr是一个使用pmxdr实现跨浏览器(仅支持postMessage的浏览器)跨域请求构造函数XDR。 它的API与相同,因此您可以将其拖放到现有代码中,而不用XHR替换XMLHttpRequest而不进行任何更改。 它还支持IE8的...

    Iframe模拟Jquery.Ajax

    5. **通信机制**:使用`window.postMessage`方法实现Iframe与主页面间的通信。这个方法允许跨窗口的数据传递,即使它们来自不同的源。发送端使用`postMessage`发送数据,接收端通过`message`事件监听数据。 6. **...

    HTML5程序设计-3期(KC014) KC014050000009 单元设计_单元9 HTML5 通信和多线程..doc

    这通常涉及使用`postMessage`和`message`事件来实现实时通信。教师会通过讲解和实例演示,让学生掌握跨文档消息传输的原理和实际操作。 其次,WebSocket是一种提供全双工通信的协议,允许客户端和服务器之间进行...

    jquery 跨iframe拖拽

    "jquery 跨iframe拖拽"的核心在于利用jQuery的拖拽插件(如jQuery UI的draggable/droppable)以及DOM操作和事件处理来实现跨IFrame通信。下面我们将分步骤解析这个过程: 1. **引入jQuery和jQuery UI**:在项目中,...

    html5 手机端类型的APP

    9. **跨文档消息传递(Cross-document messaging)**:通过`window.postMessage`方法,不同源的页面可以安全地进行通信,这对于构建复杂的单页应用(SPA)和跨窗口交互非常有用。 10. **安全性提升**:HTML5引入了...

    C# 模拟Post请求

    本主题聚焦于“C#模拟POST请求”,这是网络编程中的一个关键概念,允许开发者在应用程序中发送数据到服务器,类似于用户通过浏览器提交表单的方式。下面将详细介绍这个知识点及其相关应用。 一、理解HTTP POST请求 ...

    JavaScript 跨域之POST实现方法

    为了实现POST请求的跨域通信,本文提出了一个通过iframe和form表单提交,并使用postMessage API进行通信的方法。这种方法可以实现跨域POST请求,并且能够将请求结果返回给调用者。 首先,需要实现一个能够接受JSONP...

    模拟登录WEBQQ.zip

    7. **安全性考虑**:在实际的模拟登录过程中,需要注意防止XSS(跨站脚本攻击)和CSRF(跨站请求伪造)等安全问题。此外,由于模拟登录可能违反网站的使用协议,因此在开发此类程序时应谨慎,尊重网站的使用条款。 ...

    C# Android 嵌套H5网页 Android端外壳

    反之,JavaScript也可以通过`window.location`或`postMessage`与Android通信,实现更复杂的业务逻辑。 7. **优化和安全**:为了提高性能和安全性,开发者需要考虑缓存策略、HTTPS支持、防止跨站脚本攻击(XSS)等问题...

    c# http请求模拟

    HTTP请求模拟允许开发者在代码中复现浏览器与服务器间的通信过程,以发送GET、POST等不同类型的请求。本文将深入探讨如何在C#中实现HTTP请求模拟,并以`TestHttpPost`为例,讲解POST请求的实现。 首先,让我们了解...

    C# 模拟网页登陆

    5. **构造POST数据**:根据解析的结果,构造一个`FormUrlEncodedContent`对象,它将用于承载登录凭据和其他可能的隐藏字段。 ```csharp var formData = new Dictionary, string> { { "username", "your_username" ...

    C#实现post数据

    POST方法允许客户端(如浏览器或C#应用程序)向服务器发送数据以创建或更新资源。在C#中,我们可以使用HttpClient类来模拟HTTP请求,包括POST请求。 以下是一个简单的C# POST数据的示例代码: ```csharp using ...

    WebClient 的Post实现

    在本场景中,我们关注的是“WebClient的Post实现”,这通常涉及到使用Silverlight技术来模拟网页上的POST请求,从而实现数据上传。Silverlight是一种由微软开发的富互联网应用程序(RIA)平台,它允许开发者创建交互...

Global site tag (gtag.js) - Google Analytics