JavaScript中實現(xiàn)跨標簽頁通信的方法詳解
1.Broadcast Channel API(主流推薦)
Broadcast Channel API 允許不同標簽頁之間進行實時通信,而無需使用定時器輪詢。你可以創(chuàng)建一個共享的 Broadcast Channel,并在標簽頁之間發(fā)送消息。這樣,當其他標簽頁接收到消息時,可以立即作出響應。Broadcast Channel API 提供了更可靠和高效的跨標簽頁通信方式,避免了不必要的輪詢和性能開銷。
首先我們先創(chuàng)建一個文件crossTagMsg
const channel = new BroadcastChannel('sync-update') export function sendMsg(type: any, content: any) { channel.postMessage({ type, content }); } export function listenMsg(callback: (arg0: any) => any) { const handler = (e: { data: any; }) => { callback&&callback(e.data); } channel.addEventListener('message',handler) return ()=>{ channel.removeEventListener('message', handler) } }
很簡單的兩行代碼,一個發(fā)送,一個監(jiān)聽,監(jiān)聽返回一個移除函數(shù)
在頁面中引用函數(shù)就可以了
import {listenMsg,sendMsg} from '@/utils/crossTagMsg' const send = ()=>{ sendMsg('send',{name:'send'}) } const unmountedListenMsg = listenMsg((info:any)=>{ console.log(info.content) }) onUnmounted(unmountedListenMsg)
2.window.postMessage()
window.postMessage()
方法允許在不同的標簽頁之間進行跨域通信,并且是一種安全的方式來實現(xiàn)跨標簽頁通信。下面是使用 window.postMessage()
進行跨標簽頁通信的基本步驟:
在發(fā)送消息的標簽頁(發(fā)送方):
// 發(fā)送消息到目標標簽頁 const targetWindow = window.open('目標標簽頁的URL', '_blank'); // 打開目標標簽頁 targetWindow.postMessage('Hello from sender', '目標標簽頁的源'); // 監(jiān)聽來自目標標簽頁的響應消息 window.addEventListener('message', function(event) { if (event.source === targetWindow) { console.log('Received response:', event.data); } });
在接收消息的標簽頁(接收方):
// 監(jiān)聽來自發(fā)送方標簽頁的消息 window.addEventListener('message', function(event) { if (event.origin === '發(fā)送方標簽頁的源') { console.log('Received message:', event.data); // 發(fā)送響應消息給發(fā)送方標簽頁 event.source.postMessage('Hello from receiver', event.origin); } });
上述代碼中,發(fā)送方標簽頁使用 window.open()
方法打開目標標簽頁,并使用 targetWindow.postMessage()
發(fā)送消息到目標標簽頁。在接收方標簽頁中,使用 window.addEventListener()
監(jiān)聽來自發(fā)送方標簽頁的消息,并在收到消息后發(fā)送響應消息。
在 postMessage()
方法中,第一個參數(shù)是要發(fā)送的數(shù)據(jù),可以是字符串、數(shù)字、對象等。第二個參數(shù)是目標窗口的源(origin),用于指定接收方標簽頁的源。這是為了確保只有來自指定源的消息才會被接收和處理,以提供安全性。
需要注意的是,為了確保安全性,需要在通信的兩個標簽頁之間建立信任關系,即確保目標標簽頁的源是你所期望的,并且不接受來自未知或不信任的源的消息。
通過使用 window.postMessage()
方法,你可以在不同的標簽頁之間進行跨域通信,并傳遞數(shù)據(jù)和消息。這種方式適用于需要在不同標簽頁之間進行實時通信或共享數(shù)據(jù)的場景。
3.visibilitychange
visibilitychange可以監(jiān)聽頁面的狀態(tài),判斷頁面的顯示和隱藏,當頁面顯示的時候可以重新請求最新的數(shù)據(jù)
window.addEventListener('visibilitychange',function(e:any){ if (document.visibilityState === 'visible') { // 頁面顯示 console.log('頁面顯示'); // 執(zhí)行頁面顯示時的操作 更新數(shù)據(jù) } else if (document.visibilityState === 'hidden') { // 頁面隱藏 console.log('頁面隱藏'); // 執(zhí)行頁面隱藏時的操作 } })
4.Server-Sent Events(SSE)
Server-Sent Events(SSE)是一種用于在客戶端和服務器之間實現(xiàn)實時單向通信的技術。它允許服務器向客戶端推送數(shù)據(jù),而無需客戶端發(fā)送請求。
SSE 基于 HTTP 協(xié)議,使用了長輪詢(Long Polling)的機制??蛻舳送ㄟ^向服務器發(fā)送一個 HTTP 請求,該請求保持打開狀態(tài),直到服務器有新的數(shù)據(jù)可用或連接超時。當服務器有新數(shù)據(jù)時,它會將數(shù)據(jù)作為一個持久連接的響應發(fā)送給客戶端。
使用 SSE 的關鍵是服務器端需要發(fā)送特殊格式的數(shù)據(jù),遵循 SSE 的規(guī)范。服務器發(fā)送的數(shù)據(jù)被組織為一系列的事件(events),每個事件具有一個事件類型和數(shù)據(jù)字段??蛻舳送ㄟ^監(jiān)聽相應的事件類型來處理接收到的數(shù)據(jù)。
下面是一個使用 SSE 的示例:
服務器端代碼(Node.js):
const http = require('http'); http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', }); // 發(fā)送事件及數(shù)據(jù)到客戶端 res.write('event: message\n'); res.write('data: Hello, world!\n\n'); // 模擬每秒鐘發(fā)送一個事件 setInterval(() => { res.write('event: message\n'); res.write(`data: Current time is ${new Date().toLocaleTimeString()}\n\n`); }, 1000); }).listen(3000);
客戶端代碼(JavaScript):
const eventSource = new EventSource('/stream'); eventSource.addEventListener('message', (event) => { const data = event.data; console.log('Received message:', data); });
在上述示例中,服務器創(chuàng)建了一個 HTTP 服務器,當客戶端向 /stream
路徑發(fā)出請求時,服務器會將響應的 Content-Type
設置為 text/event-stream
,表示這是一個 SSE 連接。服務器通過發(fā)送以 "event" 和 "data" 字段組成的事件響應,向客戶端推送數(shù)據(jù)。
客戶端使用 EventSource
對象來建立 SSE 連接,并通過事件監(jiān)聽器來處理接收到的事件。在上述示例中,客戶端監(jiān)聽了 message
事件,并在事件發(fā)生時將數(shù)據(jù)打印到控制臺。
SSE 提供了一種簡單而有效的方式來實現(xiàn)服務器向客戶端的實時數(shù)據(jù)推送,適用于需要實時更新數(shù)據(jù)的應用程序,如聊天應用、實時通知、股票報價等。它相對于傳統(tǒng)的輪詢方式具有更低的延遲和更高的效率。
到此這篇關于JavaScript中實現(xiàn)跨標簽頁通信的方法詳解的文章就介紹到這了,更多相關JavaScript跨標簽頁通信內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!