GithubHelp home page GithubHelp logo

biqing / messengerjs Goto Github PK

View Code? Open in Web Editor NEW
702.0 50.0 224.0 138 KB

A common solution for cross-document communication .

Home Page: http://biqing.github.io/MessengerJS/

HTML 63.30% JavaScript 36.70%

messengerjs's Introduction

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, 以实现消息内容的扩展性.

如何使用

  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's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

messengerjs's Issues

ie6/7下的问题

msg不能为数字,否则剥离了默认的消息前缀后,数字参数不能被调用

对象传递

您好!在跨iframe有很多情况是对象或者方法的共享,但是目前是传递的字符串的方式,能否直接传递对象,然后对象共享

ie6下面数据不通啊

// 兼容IE 6/7那块
targetFunc(this.prefix + msg, window);
传递的参数跟上面this.target.postMessage(this.prefix + '|' + this.name + 'Messenger' + msg, '*');不一致,
但是监听处理那块msg.split('Messenger');还是以用了Messenger这个字符做分割,导致ie6不行。。
messenger.addTarget(window.parent.frames[1], 'iframe2');
window.parent.frames[1]这个貌似报错。。。

跨域安全性

请问父子窗口通过JSON string的方式传递消息,对于嵌入的第三方子页面,传递的消息安全性该如何保证?
是否只能通过开发者自行保证,对数据安全性进行严格校验?
谢谢~

QC 是什么

新版直接用 QC.module 直接导致代码无法执行,感觉很莫名其妙啊……

而且原文档、 Demo 也失效了,请更新一下,谢谢~

发消息丢失

hi,我在一个jsp页面用messager广播一个消息,在另外一个jsp页面用messager监听消息

  1. 消息发送页面
    var msg = " {code:10244,message:'testmessage!',datasource:'usrsys'}";
    messenger.send(msg);
  2. 消息监听页面
    messenger.listen(function (msg) {
    alert(msg);//FF浏览器此处消息被截取了,只能收到部分字符。Chorme浏览器会在消息前附加Messager= 这样的字符。
    });

在纯html页面没有发生上述问题。

浏览器:FF 32.0.3。Chorme 35.0.1916.153
联系方式:[email protected]

不传入projectName时出错

prefix = projectName.toString() || prefix;

new Messenger()的时候,不传入projectName, 会在undefined上面调用函数,导致报错。
网站的demo,能用最新的js文件吗?保持同步,有问题就能看出来了

为什么不考虑直接发送对象呢?

postMessage或者是navigator都支持直接send object,这里为什么仅仅提供字符串的msg呢?求解惑。

个人比较喜欢直接发送{eventName: 'xxx', data: object} 这种对象。

关于initListen方法中的逻辑咨询

Messenger.prototype.initListen的方法中有如下代码逻辑:
for(var i = 0; i < self.listenFunc.length; i++){
if (prefix + name === self.prefix + self.name) {
self.listenFunci;
}
}
这里可以把if的判断放到外面吗,针对一个回调时,prefix和name是不变的了吧,应该只要判断一次就可以进行for循环了,而现在这种写法是在每次循环时都要判断一次,有什么深意吗?

源码中this.target.postMessage(..., '*') ,此处的*为什么不替换成target的origin域名

平时不用postMessage,主要考虑到的是postMessage发送到其他域信息如果被存储下来,其他页可以onmessage全盘接收保存,不太安全,是否可以在发送一次消息后,获取当前域名,下次发送时,直接指定域名呢,毕竟指定了iframe的名称,通过名称map映射到对应的origin,存储origin再返回给发送发,下次发送时自动带上?更或者初始化target时,自动就做一下origin映射,是否可以?

这个能跨大域么?

我看了demo,是主域名和二级域名之间的跨域,不知道能不能跨大域,两个不同域名间能使用么?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.