首页 > 其他分享 >浏览器中多个标签页之间进行通信

浏览器中多个标签页之间进行通信

时间:2024-09-10 08:56:19浏览次数:10  
标签:postMessage 浏览器 标签 worker 通信 port data event 页面

在浏览器中多个标签页之间进行通信,可以使用以下几种方法:

非同源页面之间通信

websocket

这种方式需要服务端技术的支持

  1. 创建websocket连接
  2. 发送消息
  3. 监听消息
// 在每个标签页中,建立一个 WebSocket 连接
const socket = new WebSocket('ws://your-websocket-server');

// 在每个标签页中,添加消息监听器,以便接收来自其他标签页的消息
socket.onmessage = function (event) {
    const message = JSON.parse(event.data);
    console.log(message);
};

// 在某个标签页中发送消息
const message = {
    type: 'update',
    data:  new Date().toLocaleTimeString("en-US", { hour12: false }),
};
socket.send(JSON.stringify(message));

postMessage

注意:

  • 验证event.origin,以防止潜在的安全风险
  • 在postMessage中指定目标源,确保消息只发送到信任的源

1. 发送消息

// 假设目标是一个 iframe
const targetWindow = document.getElementById('my-iframe').contentWindow; 
// 指定目标源
targetWindow.postMessage('Hello, other origin!', 'https://target-origin.com'); 

2. 接收消息

window.addEventListener('message', (event) => {
    // 验证来源
    if (event.origin === 'https://expected-origin.com') {
        console.log('Received:', event.data);
    }
});

同源页面之间通信

注意:非同源页面之间的通信方式在同源页面之间同样适用

localStorage

localStorage受同源策略的限制,不同源的页面无法访问彼此的localStorage

storage事件:

  • 只会在不同的标签页中触发,不会在当前标签页触发
  • 对原有的数据的值进行修改时才会触发,比如原本已经有一个key为a值为b的localStorage,再执行:localStorage.setItem('a', 'b'),同样是不会触发监听函数的
// 页面1
setInterval(() => {
    localStorage.setItem("time", new Date().toLocaleTimeString("en-US", { hour12: false }));
}, 1000);
// 页面2
window.addEventListener('storage', (event) => {
    console.log(event);
});
// 页面2 或者这样写
window.onstorage = (event) => {
    console.log(event)
};

SharedWorker

sharedWorker:共享线程,同源策略下,多个运行环境共用同一个线程,包括数据

1. 首先在服务器上要有一个处理通信数据的js,比如worker.js

let data = ''
onconnect = function (e) {
  let port = e.ports[0]
  
  port.onmessage = function (e) {
    if (e.data === 'get') {       
      // 如果是get 则返回数据给客户端
      port.postMessage(data)
    } else {                      
      // 否则把数据保存
      data = e.data
    }
  }
}

2. A页面负责传输数据

if (typeof Worker === "undefined") {
    alert('当前浏览器不支持webworker')
} else {
    let worker = new SharedWorker('worker.js')
    window.worker = worker
    let i = 0;
    document.querySelector('button').onclick = function () {
        window.worker.port.postMessage('发送信息给worker' + i++);
    }
}

3. B页面接收数据

// 打开页面后注册SharedWorker,显示指定worker.port.start()方法建立与worker间的连接
if (typeof Worker === "undefined") {
    alert('当前浏览器不支持webworker')
} else {
    let worker = new SharedWorker('worker.js')
    worker.port.addEventListener('message', (e) => {
        console.log('来自worker的数据:', e.data)
    }, false)
    worker.port.start();
    window.worker = worker;
}
// 获取和发送消息都是调用postMessage方法,这里约定传递'get'表示获取数据。
document.querySelector('button').onclick = function() {
    window.worker.port.postMessage('get');
}

Broadcast Channel

BroadCast Channel 可以帮我们创建一个用于广播的通信频道;当所有页面都监听同一频道的消息时,其中某一个页面通过它发送的消息就会被其他所有页面收到

1. 创建频道

const channel = new BroadcastChannel('my_channel');

2. 发送消息

channel.postMessage('Hello from another tab!');

3. 接收消息

channel.onmessage = (event) => {
    console.log('Received:', event.data);
};

4. 关闭频道(可选)

channel.close();

标签:postMessage,浏览器,标签,worker,通信,port,data,event,页面
From: https://blog.csdn.net/qq_45937484/article/details/141756012

相关文章