在浏览器中多个标签页之间进行通信,可以使用以下几种方法:
非同源页面之间通信
websocket
这种方式需要服务端技术的支持
- 创建websocket连接
- 发送消息
- 监听消息
// 在每个标签页中,建立一个 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