兩個瀏覽器窗口間通信總結


兩個瀏覽器窗口間通信總結

1、localStorage

一個窗口更新localStorage,另一個窗口監聽window對象的”storage”事件,來實現通信。
注:兩個頁面要同源(URL的協議、域名和端口相同)

// 本窗口的設值代碼
localStorage.setItem('aaa', (Math.random()*10).toString())

// 其他窗口監聽storage事件
window.addEventListener("storage", function (e) {
  console.log(e)
  console.log(e.newValue)
})

2、WebSocket

所有的WebSocket都監聽同一個服務器地址,利用send發送消息,利用onmessage獲取消息的變化,不僅能窗口,還能跨瀏覽器,兼容性最佳,只是需要消耗點服務器資源。

var ws = new WebSocket("ws://localhost:3000/")
ws.onopen = function (event) {
  // 或者把此方法注冊到其他事件中,即可與其他服務器通信
  ws.send({now : Date.now()}); // 通過服務器中轉消息
};
ws.onmessage = function (event) {
  // 消費消息
  console.log(event.data);
}

3、postMessage

借助iframe 或 window.open
回顧一下API

otherWindow.postMessage(message, targetOrigin, [transfer]);
  • otherWindow
    其他窗口的一個引用,比如iframe的contentWindow屬性、執行window.open返回的窗口對象、或者是命名過或數值索引的window.frames。
  • message
    將要發送到其他 window的數據。它將會被結構化克隆算法序列化。這意味着你可以不受什么限制的將數據對象安全的傳送給目標窗口而無需自己序列化。
  • targetOrigin
    通過窗口的origin屬性來指定哪些窗口能接收到消息事件,其值可以是字符串""(表示無限制)或者一個URI。在發送消息的時候,如果目標窗口的協議、主機地址或端口這三者的任意一項不匹配targetOrigin提供的值,那么消息就不會被發送;只有三者完全匹配,消息才會被發送。這個機制用來控制消息可以發送到哪些窗口;例如,當用postMessage傳送密碼時,這個參數就顯得尤為重要,必須保證它的值與這條包含密碼的信息的預期接受者的origin屬性完全一致,來防止密碼被惡意的第三方截獲。如果你明確的知道消息應該發送到哪個窗口,那么請始終提供一個有確切值的targetOrigin,而不是。不提供確切的目標將導致數據泄露到任何對數據感興趣的惡意站點。
  • transfer 可選
    是一串和message 同時傳遞的 Transferable 對象. 這些對象的所有權將被轉移給消息的接收方,而發送一方將不再保有所有權。
/*
 * A窗口的域名是<http://example.com:8080>,以下是A窗口的script標簽下的代碼:
 */

var popup = window.open(...popup details...);

// 如果彈出框沒有被阻止且加載完成

// 這行語句沒有發送信息出去,即使假設當前頁面沒有改變location(因為targetOrigin設置不對)
popup.postMessage("The user is 'bob' and the password is 'secret'",
                  "https://secure.example.net");

// 假設當前頁面沒有改變location,這條語句會成功添加message到發送隊列中去(targetOrigin設置對了)
popup.postMessage("hello there!", "http://example.org");

function receiveMessage(event)
{
  // 我們能相信信息的發送者嗎?  (也許這個發送者和我們最初打開的不是同一個頁面).
  if (event.origin !== "http://example.org")
    return;

  // event.source 是我們通過window.open打開的彈出頁面 popup
  // event.data 是 popup發送給當前頁面的消息 "hi there yourself!  the secret response is: rheeeeet!"
}
window.addEventListener("message", receiveMessage, false);


/*
 * 彈出頁 popup 域名是<http://example.org>,以下是script標簽中的代碼:
 */

//當A頁面postMessage被調用后,這個function被addEventListenner調用
function receiveMessage(event)
{
  // 我們能信任信息來源嗎?
  if (event.origin !== "http://example.com:8080")
    return;

  // event.source 就當前彈出頁的來源頁面
  // event.data 是 "hello there!"

  // 假設你已經驗證了所受到信息的origin (任何時候你都應該這樣做), 一個很方便的方式就是把enent.source
  // 作為回信的對象,並且把event.origin作為targetOrigin
  event.source.postMessage("hi there yourself!  the secret response " +
                           "is: rheeeeet!",
                           event.origin);
}

window.addEventListener("message", receiveMessage, false);

4、cookie + setInterval【差】

在頁面A設置一個使用 setInterval 定時器不斷刷新,檢查 Cookies 的值是否發生變化,如果變化就進行刷新的操作。

由於 Cookies 是在同域可讀的,所以在頁面 B 審核的時候改變 Cookies 的值,頁面 A 自然是可以拿到的。

這樣做確實可以實現我想要的功能,但是這樣的方法相當浪費資源。雖然在這個性能過盛的時代,浪費不浪費也感覺不出來,但是這種實現方案,確實不夠優雅。

5、SharedWorker

HTML5 中的 Web Worker 可以分為兩種不同線程類型,一個是專用線程 Dedicated Worker,一個是共享線程 Shared Worker。

  • Dedicated Worker直接使用new Worker()即可創建,這種webworker是當前頁面專有的。。
  • SharedWorker可以被多個window、標簽頁、iframe共同使用,但必須保證這些標簽頁都是同源的(相同的協議,主機和端口號)

6、直接引用

適用於兩個頁面在同一域;可以傳遞對象數據(對象數據使用 instanceof 做類型判斷時有坑);參考 window.open;

原文地址:https://segmentfault.com/a/1190000016927268


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM