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.html

簡單地說, 若是你不用兼容IE6/7的iframe通訊, 你就不須要這套方案了..git

適用場景

此方案適用於如下跨域情形:github

  • 父窗口與iframe之間通訊
  • 多個iframe之間通訊

*上述全部狀況, 都需確保對不一樣域的頁面有修改權限, 並同時加載MessengerJS算法

*IE下不支持跨窗口通訊json

常見跨源問題有:跨域

  • 跨子域
  • 跨全域
  • 跨協議(HTTP與HTTPS)

理念: 關於"信使"的一切

理解設計理念對實際使用有幫助做用, 高手能夠直接跳到下方使用說明 : )安全

在跨文檔通訊中, 一切消息都是以字符串形式存在, 能夠視其爲"報文", 所以負責派送和接受信件的角色, 咱們稱其爲"信使"(Messenger).ide

Messenger的職責很簡單, 主要分爲 發送消息(send) 與 監聽消息(listen), 而消息的內容都是字符串. 實際使用中, 最好不要直接使用簡單的字符串, 而建議使用結構化的消息(JSON String). 具體邏輯請自行實現: 發送前將json內容stringify, 收到後進行parse, 以實現消息內容的擴展性.函數

如何使用

  1. 在須要通訊的文檔中(父窗口和iframe們), 都確保引入MessengerJSthis

  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

相關文章
相關標籤/搜索