跨标签页通信

  • Broadcast Channel API(主流推荐):Broadcast Channel API 允许不同标签页之间进行实时通信,而无需使用定时器轮询。你可以创建一个共享的 Broadcast Channel,并在标签页之间发送消息。这样,当其他标签页接收到消息时,可以立即作出响应。Broadcast Channel API 提供了更可靠和高效的跨标签页通信方式,避免了不必要的轮询和性能开销。

首先我们先创建一个文件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) 
    }
} 

很简单的两行代码,一个发送,一个监听,监听返回一个移除函数

在页面中引用函数就可以了

import {listenMsg,sendMsg} from '@/utils/crossTagMsg'

const send = ()=>{
    sendMsg('send',{name:'send'})
}

const unmountedListenMsg = listenMsg((info:any)=>{
    console.log(info.content)
})

onUnmounted(unmountedListenMsg)

 

  • window.postMessage() 方法允许在不同的标签页之间进行跨域通信,并且是一种安全的方式来实现跨标签页通信。下面是使用 window.postMessage() 进行跨标签页通信的基本步骤:

  在发送消息的标签页(发送方):

// 发送消息到目标标签页
const targetWindow = window.open('目标标签页的URL', '_blank'); // 打开目标标签页
targetWindow.postMessage('Hello from sender', '目标标签页的源');

// 监听来自目标标签页的响应消息
window.addEventListener('message', function(event) {
  if (event.source === targetWindow) {
    console.log('Received response:', event.data);
  }
});

  在接收消息的标签页(接收方):

// 监听来自发送方标签页的消息
window.addEventListener('message', function(event) {
  if (event.origin === '发送方标签页的源') {
    console.log('Received message:', event.data);

    // 发送响应消息给发送方标签页
    event.source.postMessage('Hello from receiver', event.origin);
  }
});

上述代码中,发送方标签页使用 window.open() 方法打开目标标签页,并使用 targetWindow.postMessage() 发送消息到目标标签页。在接收方标签页中,使用 window.addEventListener() 监听来自发送方标签页的消息,并在收到消息后发送响应消息。

在 postMessage() 方法中,第一个参数是要发送的数据,可以是字符串、数字、对象等。第二个参数是目标窗口的源(origin),用于指定接收方标签页的源。这是为了确保只有来自指定源的消息才会被接收和处理,以提供安全性。

需要注意的是,为了确保安全性,需要在通信的两个标签页之间建立信任关系,即确保目标标签页的源是你所期望的,并且不接受来自未知或不信任的源的消息。

通过使用 window.postMessage() 方法,你可以在不同的标签页之间进行跨域通信,并传递数据和消息。这种方式适用于需要在不同标签页之间进行实时通信或共享数据的场景。

 

 

  • visibilitychange 可以监听页面的状态,判断页面的显示和隐藏,当页面显示的时候可以重新请求最新的数据
window.addEventListener('visibilitychange',function(e:any){
    if (document.visibilityState === 'visible') {
        // 页面显示
        console.log('页面显示');
        // 执行页面显示时的操作 更新数据
    } else if (document.visibilityState === 'hidden') {
        // 页面隐藏
        console.log('页面隐藏');
        // 执行页面隐藏时的操作
    }
})
  • Server-Sent Events(SSE)是一种用于在客户端和服务器之间实现实时单向通信的技术。它允许服务器向客户端推送数据,而无需客户端发送请求。

    SSE 基于 HTTP 协议,使用了长轮询(Long Polling)的机制。客户端通过向服务器发送一个 HTTP 请求,该请求保持打开状态,直到服务器有新的数据可用或连接超时。当服务器有新数据时,它会将数据作为一个持久连接的响应发送给客户端。

    使用 SSE 的关键是服务器端需要发送特殊格式的数据,遵循 SSE 的规范。服务器发送的数据被组织为一系列的事件(events),每个事件具有一个事件类型和数据字段。客户端通过监听相应的事件类型来处理接收到的数据。

下面是一个使用 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',
  });

  // 发送事件及数据到客户端
  res.write('event: message\n');
  res.write('data: Hello, world!\n\n');

  // 模拟每秒钟发送一个事件
  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);
});

在上述示例中,服务器创建了一个 HTTP 服务器,当客户端向 /stream 路径发出请求时,服务器会将响应的 Content-Type 设置为 text/event-stream,表示这是一个 SSE 连接。服务器通过发送以 "event" 和 "data" 字段组成的事件响应,向客户端推送数据。

客户端使用 EventSource 对象来建立 SSE 连接,并通过事件监听器来处理接收到的事件。在上述示例中,客户端监听了 message 事件,并在事件发生时将数据打印到控制台。

SSE 提供了一种简单而有效的方式来实现服务器向客户端的实时数据推送,适用于需要实时更新数据的应用程序,如聊天应用、实时通知、股票报价等。它相对于传统的轮询方式具有更低的延迟和更高的效率。

posted @ 2023-11-17 18:29  小不点灬  阅读(80)  评论(0编辑  收藏  举报