postMessage到底有多好用

postMessage是什麼?

postMessage()方法容許來自不一樣源的腳本採用異步方式進行有限的通訊,能夠實現跨文本檔、多窗口、跨域消息傳遞。html

Html5中的postMessage解決跨域,跨窗口消息傳遞

postMessage的優勢html5

  1. 兩個跨域頁面的消息傳遞
  2. 多窗口之間的消息傳遞
  3. 嵌套iframe的數據傳遞
postMessage()

postMessage()方法容許來自不一樣源的腳本採用異步方式進行有限的通訊,能夠實現跨文本檔、多窗口、跨域消息傳遞。 postMessage(data,origin)方法接受兩個參數json

  1. data:要傳遞的數據,html5規範中提到該參數能夠是JavaScript的任意基本類型或可複製的對象,然而並非全部瀏覽器都作到了這點兒,部分瀏覽器只能處理字符串參數,因此咱們在傳遞參數的時候須要使用JSON.stringify()方法對對象參數序列化,在低版本IE中引用json2.js能夠實現相似效果。
  2. origin:字符串參數,指明目標窗口的源,協議+主機+端口號[+URL],URL會被忽略,因此能夠不寫,這個參數是爲了安全考慮,postMessage()方法只會將message傳遞給指定窗口,固然若是願意也能夠建參數設置爲"*",這樣能夠傳遞給任意窗口,若是要指定和當前窗口同源的話設置爲"/"。

例如:跨域

// A頁面 [http://a.com]
const data = document.getElementById('name').value;
window.frames[0].postMessage(data,'http://b.com');
複製代碼

在B頁面監聽message事件,獲取傳遞過來的數據瀏覽器

// B頁面 [http://b.com]
window.addEventListener('message', function(ev) {
    // 當咱們是父子窗口進行消息傳遞時,可使用此判斷,只接受父窗口傳遞來的消息,
    if (ev.source !== window.parent) return;
    var data = ev.data;
    console.info('message from parent:', data);
}, false);
複製代碼

經過這樣的一個傳遞和接受的過程能夠實現一個完整的消息傳遞。無論A,B是否跨域,是否存在嵌套關係,均可以使用postMessage的方式實現消息傳遞。安全

MessageEvent的屬性
  • data:從源端傳遞來的message
  • source:發送消息的窗口對象
  • origin:發送消息窗口的源(協議+主機+端口號)

當咱們只處理某些源發送過來的消息時,咱們可使用origin來作判斷,只處理某一些源的message,這樣方便過濾一些沒必要要的值。bash

解決問題

最近遇到一個問題,本身的代碼【A_child】是經過Iframe的方式放在A系統中的,由於代碼中須要A系統登陸時的用戶信息去獲取資源,因此須要A系統中的cookie信息。目前的處理方式就是講個人代碼部署到A系統的服務器上,而後指定不一樣的端口,這樣使用嵌入iframe的方式實現cookie共享。可是缺點就是每次更新代碼都須要A系統的負責人去作更新。耗費了大量的人力和時間成本。服務器

注意:相同的域名,不一樣的端口能夠共享cookie信息。微信

最近爲了減輕本身的工做負擔,決定寫一箇中間層頁面,放在A系統下,菜單的指向不變,只是在中間層的頁面中在作一次iframe嵌套,而且在這個頁面中將A系統中的cookie信息使用postMessage的方式發送給origin端。cookie

注意:由於我本身代碼進入時就須要帶着用戶信息請求表格數據,因此頁面的全部操做必須在收到message後才進行。因此就有了下面的這個代碼

window.addEventListener('message', (ev) => {
    if (ev.source !== window.parent) return;
    const data = ev.data; 
    ...
    ...
    ...
    Vue.prototype.userInfo = data;
    new Vue({
        el: '#app',
        router,
        store,
        render: h => h(renderComponents),
    });
}, false);
複製代碼
固然解決嵌套iframe跨域傳值的問題,還有另外的兩個方法。
  1. 使用hash值,將須要傳遞的值data放在iframe中src的hash中。
  2. 子頁面傳值給父頁面,能夠藉助C頁面【C和A必須時同域的】,A中嵌套B,B中嵌套C,B要想A傳值,可使用C做爲一個事件BUS,B中的數據先傳遞給C,而後在經過C傳遞數據給A。【此方法筱筱沒用過啊】,大概方法是這樣的。
總結

html5新增的特性,postMessge主要是更方便的解決了多頁面的消息傳遞,而且有效解決了跨域問題。使用起來更加的簡單方便。不過根據本身的需求選擇不一樣的處理方式。

歡迎關注微信公衆號

相關文章
相關標籤/搜索