MessengerJS
跨文档通信解决方案
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, 以实现消息内容的扩展性.
如何使用
在需要通信的文档中(父窗口和iframe们), 都确保引入MessengerJS
每一个文档(
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');
在发送消息前,确保目标文档已经监听了消息事件。
// iframe中 - 监听消息
// 回调函数按照监听的顺序执行
messenger.listen(function(msg){
alert("收到消息: " + msg);
});
父窗口想给iframe发消息,它怎么知道iframe的存在呢?添加一个消息对象吧。
// 父窗口中 - 添加消息对象, 明确告诉父窗口iframe的window引用与名字
messenger.addTarget(iframe1.contentWindow, 'iframe1'); // 父窗口中 - 可以添加多个消息对象
messenger.addTarget(iframe2.contentWindow, 'iframe2');
一切ready,发消息吧~发送消息有两种方式。 (以父窗口向iframe发消息为例)
// 父窗口中 - 向单个iframe发消息
messenger.targets['iframe1'].send(msg1);
messenger.targets['iframe2'].send(msg2); // 父窗口中 - 向所有目标iframe广播消息
messenger.send(msg);
现在看到iframe收到消息的alert提示了吗?
Demo
http://biqing.github.io/labs/messenger/parent.html
关于消息安全性
由于任何iframe都可以收到广播的消息,建议传递消息时使用JSON String的形式,使用一个字段做消息有效性的验证。如果怕一个固定值(如项目名)不安全,可以使用一个简单的加密算法,并对业务脚本进行压缩混淆,此时的安全风险可以降到最低。
问题与建议
使用中难免遇到问题,欢迎提问与建议 : )
MessengerJS的更多相关文章
- 附实例!实现iframe父窗体与子窗体的通信
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由前端林子发表于云+社区专栏 本文主要会介绍如何基于MessengerJS,实现iframe父窗体与子窗体间的通信,传递数据信息.同时本 ...
随机推荐
- nl命令
nl (Number of Lines) 将指定的文件添加行号标注后写到标准输出.如果不指定文件或指定文件为"-" ,程序将从标准输入读取数据. 选项: -b, --body-nu ...
- 金蝶k/3 现金流量表编制口诀
现金流量表编制口诀 现金流量表是会计考试中十分令人头疼的内容,丢三落四是现金流量表编制中最容易出现的错误.下面的口诀基本上概括了现金流量表的全部编制过程.口诀的具体内容如何理解,我们在口诀后边详细阐述 ...
- Redis实战 - 1.String和计数器
在.NET Core 项目中操练String 使用 StackExchange.Redis 访问 Redis static void Main(string[] args) { using (Conn ...
- 将Emacs Org任务树导出至Freeplane思维导图
Emacs Org mode作为实施GTD方法的任务与项目管理工具是极为强大和有效的.尽管如此,我在使用过程中亦发现了一个因Emacs文本操作模式而难以解决的情况,即对于具有复杂结构与大量细节的项目, ...
- C#学习-接口的成员
在接口中定义方法不能添加任何访问修饰符,因为接口中的方法是默认为public,如果显式地指定了修饰符,则会出现编译时错误. 定义玩接口之后,如果有类想继承该接口,则它必须显示接口中定义的所有方法. 在 ...
- 美团小程序框架mpvue入门
mpvue 主要特性 使用 mpvue 开发小程序,你将在小程序技术体系的基础上获取到这样一些能力: 1. 彻底的组件化开发能力:提高代码复用性 2. 完整的 Vue.js 开发体验 3. 方便的 V ...
- 微信小程序--家庭记账本开发--02
代码文件的了解 对于一个程序的开发,代码的了解的必须的,不同的后缀名文件有着不同的作用,通过学习,对于微信小程序开发中的文件有了自己的理解. 文件概述 一个微信小程序一般有有pages文件夹,util ...
- mongodb 遇到的问题一 Error: connect ECONNREFUSED 127.0.0.1:27017
node配合mongodb是配置完成后,访问时出现 Error: connect ECONNREFUSED 127.0.0.1:27017,的报错 原因在于你的mongodb数据库没开, node下的 ...
- TP5在前端时间戳转换为时间格式
value="{:date('Y-m-d H:i:s',$data['add_date'])}" 例如: <td>{:date('Y-m-d H:i:s',$d[' ...
- vscode + electron 提示:无法连接到legacy请采用inspector解决办法
首先,你的程序是可以直接运行的,在命令行中可以运行,只是在vsCode中,运行一段时间就被这个提示弹出. 解决方法: 先在launch.json 中加上"protocol":&qu ...