跨文档通信解决方案

Since modern browsers have native cross-document communication method(the PostMeessage API, and the "message" event), this project is primarily for the developers who still need to care about the compatiblity in IE6/7, especially the developers in China, I will use Chinese in this document. If you guys wanna learn some more, please leave an issue, and I will provide the english version of help.

简单地说, 如果你不用兼容IE6/7的iframe通信, 你就不需要这套方案了..

适用场景

此方案适用于以下跨域情形:

  • 父窗口与iframe之间通信
  • 多个iframe之间通信

*上述所有情况, 都需确保对不同域的页面有修改权限, 并同时加载MessengerJS

*IE下不支持跨窗口通信

常见跨源问题有:

  • 跨子域
  • 跨全域
  • 跨协议(HTTP与HTTPS)

理念: 关于"信使"的一切

理解设计理念对实际使用有帮助作用, 高手可以直接跳到下方使用说明 : )

在跨文档通信中, 一切消息都是以字符串形式存在, 可以视其为"报文", 因此负责派送和接受信件的角色, 我们称其为"信使"(Messenger).

Messenger的职责很简单, 主要分为 发送消息(send) 与 监听消息(listen), 而消息的内容都是字符串. 实际使用中, 最好不要直接使用简单的字符串, 而建议使用结构化的消息(JSON String). 具体逻辑请自行实现: 发送前将json内容stringify, 收到后进行parse, 以实现消息内容的扩展性.

如何使用

  1. 在需要通信的文档中(父窗口和iframe们), 都确保引入MessengerJS

  2. 每一个文档(document),都需要自己的Messenger与其他文档通信。即每一个window对象都对应着一个,且仅有一个Messenger对象,该Messenger对象会负责当前window的所有通信任务。每个Messenger对象都需要唯一的名字,这样它们才可以知道跟谁通信。另外,推荐指定项目名称(类似命名空间的作用),以增强代码健壮性与组件复用性,避免未来与其他项目冲突。(注意: 项目名称应使用 字符串类型 )

     // 父窗口中 - 初始化Messenger对象
    // 推荐指定项目名称, 避免Mashup类应用中, 多个开发商之间的冲突
    var messenger = new Messenger('Parent', 'projectName'); // iframe中 - 初始化Messenger对象
    // 注意! Messenger之间必须保持项目名称一致, 否则无法匹配通信
    var messenger = new Messenger('iframe1', 'projectName'); // 多个iframe, 使用不同的名字
    var messenger = new Messenger('iframe2', 'projectName');
  3. 在发送消息前,确保目标文档已经监听了消息事件。

     // iframe中 - 监听消息
    // 回调函数按照监听的顺序执行
    messenger.listen(function(msg){
    alert("收到消息: " + msg);
    });
  4. 父窗口想给iframe发消息,它怎么知道iframe的存在呢?添加一个消息对象吧。

     // 父窗口中 - 添加消息对象, 明确告诉父窗口iframe的window引用与名字
    messenger.addTarget(iframe1.contentWindow, 'iframe1'); // 父窗口中 - 可以添加多个消息对象
    messenger.addTarget(iframe2.contentWindow, 'iframe2');
  5. 一切ready,发消息吧~发送消息有两种方式。 (以父窗口向iframe发消息为例)

     // 父窗口中 - 向单个iframe发消息
    messenger.targets['iframe1'].send(msg1);
    messenger.targets['iframe2'].send(msg2); // 父窗口中 - 向所有目标iframe广播消息
    messenger.send(msg);
  6. 现在看到iframe收到消息的alert提示了吗?

Demo

http://biqing.github.io/labs/messenger/parent.html

关于消息安全性

由于任何iframe都可以收到广播的消息,建议传递消息时使用JSON String的形式,使用一个字段做消息有效性的验证。如果怕一个固定值(如项目名)不安全,可以使用一个简单的加密算法,并对业务脚本进行压缩混淆,此时的安全风险可以降到最低。

问题与建议

使用中难免遇到问题,欢迎提问与建议 : )

提交Issue

MessengerJS的更多相关文章

  1. 附实例!实现iframe父窗体与子窗体的通信

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由前端林子发表于云+社区专栏 本文主要会介绍如何基于MessengerJS,实现iframe父窗体与子窗体间的通信,传递数据信息.同时本 ...

随机推荐

  1. HttpClient当HTTP连接的时候出现大量CLOSE_WAIT连接(转)

    ESTABLISHED 表示正在进行网络连接的数量 TIME_WAIT 表示表示等待系统主动关闭网络连接的数量 CLOSE_WAIT 表示被动等待程序关闭的网络连接数量 上篇文章给出了解决TIME_W ...

  2. [慢更]Sublime Text 快捷键及使用过的插件

    整理自己常用的sublime text命令和插件 1.pretty json Json 快速格式化,免去url访问json站点的烦恼. 摘自:https://segmentfault.com/a/11 ...

  3. CodeForces 286E Ladies' Shop 多项式 FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8781889.html 题目传送门 - CodeForces 286E 题意 首先,给你$n$个数(并告诉你$m$ ...

  4. Linux内核原理与分析-第一周作业

    本科期间,学校开设过linux相关的课程,当时的学习方式主要以课堂听授为主.虽然老师也提供了相关的学习教材跟参考材料,但是整体学下来感觉收获并不是太大,现在回想起来,主要还是由于自己课下没有及时动手实 ...

  5. python 单行写法

    if not any([_ in fingers for _ in finger_ids])

  6. Selenium获取当前窗口句柄与切换回原窗口句柄

    Selenium通过window_handles获取当前窗口句柄,进行页面元素操作 切换回原窗口句柄,进行元素操作 代码如下:(python版) __author__ = 'liuke' import ...

  7. 读取gzmt.csv文件,计算均值及概率

    问题: 读取gzmt.csv文件所有数据,选取收盘价格(倒数第二列),计算20天均值,权重取成交量(选做:时间权重为半衰期为15天):将该均值修剪为超过600的都设置为1000,并打印出该均值超过55 ...

  8. CSS3_过渡_2D 变换_瓶体旋转_动态时钟

    1. 过渡 transition 允许 CSS 的属性值在一定时间内平滑的过渡, 在鼠标点击,鼠标滑过或对属性改变中触发,并圆滑的改变 CSS 的属性值 简写属性: #box { width: 300 ...

  9. c#中string的一些基本用法

    .string的Split方法的使用 这个例子就是通过制定的符号来将词组分开,Splite(分割的字符,分割的份数) using System; using System.Collections; p ...

  10. mysql 5.7.21 解压版安装配置方法图文教程

    引用:https://www.jb51.net/article/140951.htm 1.首先,你要下载MySQL解压版,下载地址,图解: 2.解压安装包,根据自己的喜好选择路径,我选择的路径是C:\ ...