1. 程式人生 > 實用技巧 >學習筆記-瀏覽器內多個標籤頁之間的通訊

學習筆記-瀏覽器內多個標籤頁之間的通訊

Redux vuex 這個是單頁面應用裡跨頁面狀態管理 多頁應用 跨頁面資料傳遞

本題主要考察多頁應用中各個頁籤之間資料互動的技術手段。

實現多頁通訊主要有利用

  • 瀏覽器資料儲存方式:瀏覽器資料儲存的方式主要用本地儲存方式解決,即呼叫localStorage、Cookie等本地儲存方式。
  • 伺服器方式:主要使用websocket技術使多頁籤都監聽伺服器推送事件來獲得其他頁簽發送的資料。

瀏覽器儲存:

第一種:localStorage:

在一個標籤頁裡面使用localStorage.setItem(key,value)新增(修改、刪除)內容;在另一個標籤頁裡面監聽storage事件。即可得到localstorge

儲存的值,實現不同標籤頁之間的通訊。

//新增
localStorage.setItem(key,value)
//刪除
localStorage.removeItem(key,value)

//新增監聽storage的變化
window.onload=function(){
window.addEventListener('storage',function(event){
//event事件物件包含domainnewValueoldValuekey
console.log(event.key+'='+event.newValue);
})
}

第二種:cookie+setInterval:

將要傳遞的資訊儲存在cookie中,每隔一定時間讀取cookie資訊, 即可隨時獲取要傳遞的資訊。

在A頁面將需要傳遞的訊息儲存在cookie當中

在B頁面設定setInterval,以一定的時間間隔去讀取cookie的值。(不停地問cookie)

//設定cookie
document.cookie="name="+name;

//獲取cookie
functiongetCookie(key){
const_string='{"';
_string+=document.cookie.replace(/;\s+/gim,'","').replace(/=/gim,'":"');
_string+='"}'[key];

returnJSON.parse(_string);
}

監聽伺服器事件

第一種:websocket通訊

WebSocket 是全雙工(full-duplex)通訊自然可以實現多個標籤頁之間的通訊(伺服器可以主動發資料給瀏覽器;瀏覽器也可以主動發資料給伺服器)。

WebSocket 是HTML 5新增的協議,它的目的是在瀏覽器和伺服器之間建立一個不受限的雙向通訊的通道,比如說,伺服器可以在任意時刻傳送訊息給瀏覽器。

為什麼傳統的HTTP協議不能做到WebSocket實現的功能?這是因為HTTP協議是一一個請求-響應協議,請求必須先由瀏覽器發給伺服器,伺服器才能響應這個請求,再把資料傳送給瀏覽器。

也有人說,HTTP協議其實也能實現啊,比如用輪詢或者Comet。這個機制的缺點一是實時性不夠, 二是頻繁的請求會給伺服器帶來極大的壓力。Comet本質上也是輪詢,但是在沒有訊息的情況下,伺服器先拖一段時間, 等到有訊息了再回復。這個機制暫時地解決了實時性問題,但是它帶來了新的問題:以多執行緒模式執行的伺服器會讓大部分執行緒大部分時間都處於掛起狀態,極大地浪費伺服器資源。另外,一個HTTP連線在長時間沒有資料傳輸的情況下,鏈路上的任何一個閘道器都可能關閉這個連線,而閘道器是我們不可控的,這就要求Comet連線必須定期發一些ping資料表示連線正常工作”。

WebSocket並不是全新的協議,而是利用了HTTP協議來建立連線。

為什麼WebSocket連線可以實現全雙工通訊而HTTP連線不行呢?

實際上通訊協議是建立在TCP協議之上的, TCP協議本身就實現了全雙工通訊,但是HTTP協議的請求-應答機制限制了全雙工通訊。WebSocket連線建立以後,其實只是簡單規定了一下:接下來,咱們通訊就不使用HTTP協議了,直接互相發資料吧。安全的WebSocket連線機制和HTTPS類似。首先,瀏覽器用wss://xx建立WebSocket連線時, 會先通過HTTPS建立安全的連線,然後,該HTTPS連線升級為WebSocket連線,底層通訊走的仍然是安全的SSL/TLS協議。

WebSocket連線必須由瀏覽器發起,特點:

(1)建立在 TCP 協議之上,伺服器端的實現比較容易。

(2)與 HTTP 協議有著良好的相容性。預設埠也是80和443,並且握手階段採用 HTTP 協議,因此握手時不容易遮蔽,能通過各種 HTTP 代理伺服器。

(3)資料格式比較輕量,效能開銷小,通訊高效。

(4)可以傳送文字,也可以傳送二進位制資料。

(5)沒有同源限制,客戶端可以與任意伺服器通訊。

(6)協議識別符號是ws (如果加密,則為wss),伺服器網址就是URL。

示例:瀏覽器端程式碼

//CreateWebSocketconnection.
constsocket=newWebsocket("ws://localhost:8080");

//Connectionopened
socket.addEventListener("open",function(event){
socket.send("HelloServer!");
});

//Listenformessages
socket.addEventListener("message",function(event){
console.log("Messagefromserver",event.data);
});

第二種:html5瀏覽器的新特性SharedWorker大

普通的 webworker 直接使用 new Worker() 即可建立,這種 webworker 是當前頁面專有的。然後還有種共享 worker(SharedWorker),這種是可以多個標籤頁、iframe共同使用的。SharedWorker 可以被多個 window 共同使用,但必須保證這些標籤頁都是同源的(相同的協議,主機和埠號)

首先新建一個is檔案worker.js, 具體程式碼如下: .

//shareWorker所要用到的js檔案,不必打包到專案中,直接放到伺服器即可

letdata="";
letonconnect=function(event){
letport=event.ports[0];
port.onmessage=function(e){
if(e.data==="get"){
port.postMessage(data);
}else{
data=e.data;
}
};
};

示例程式碼:

try{
varworker=newSharedWorker("worker.js");
vargetBtn=document.getElementById("get");
varsetBtn=document.getElementById("set");
vartxt=document.getElementById("txt");
varlog=document.getElementById("log");

worker.port.addEventListener("message",function(e){
log.innerHTML=e.data;
console.log("---獲取到資料e.data---",e.data);
});

worker.port.start();

setBtn.addEventListener(
"click",
function(e){
worker.port.postMessage(txt.value);
},
false
);

getBtn.addEventListener(
"click",
function(e){
worker.port.postMessage("get");
},
false
);
}catch(error){
console.log("---error---",error);
}