实现浏览器多标签页之间通信
需求场景:浏览器多个标签页之间需要进行数据通信。
方法1:localStorage实现通信
localStorage的特点:
- 同域共享存储空间
- 持久化将数据存储来浏览器
- 提供事件监听localStorage变化
简单实现:
A标签页:
window.addEventListener("storage", (e) => {
console.info("localStorage发生变化:", e)
})
B标签页:
localStorage.setItem("data", '100');
注意:
- 同域共享,如果多个标签页跨域了,那么数据将无法共享(域名、端口、协议)。
- 使用storage事件监听localStorage变化,也可以直接通过localStorage.getItem()获取数据。
方法2:使用websocket
原理:广播和接收。
简单实现:
搭建websocket服务器实现多标签页通信,实现比较复杂且需要增加一个服务器导致增加了总体服务器压力。
注意:
- 没有同源共享策略,即可实现跨域共享。
- 不建议使用websocket来进行多标签页通信,因为使用websocket会增加服务器的负担。
方法3:使用WebWorker中的SharedWorker
SharedWorker是WebWorker中的一种。
原理:广播和接收。
简单实现:
// worker.js ---初始化配置文件
const set = new Set()
onconnect = event => {
const port = event.ports[0]
set.add(port)
// 接收信息
port.onmessage = e => {
// 广播信息
set.forEach(p => {
p.postMessage(e.data)
})
}
// 发送信息
port.postMessage("worker广播信息")
}
A标签页:
const worker = new SharedWorker('./worker.js')
worker.port.onmessage = e => {
console.info("pageA收到消息", e.data)
}
B标签页:
const worker = new SharedWorker('./worker.js')
worker.port.postMessage(`100`)
注意:
- 有同源共享策略限制,跨域不共享。
- SharedWorker缺点:调试不太方便、兼容性不太好(IE已死,推荐使用)。
方法4:使用cookie + setInterval实现
cookie特点:
- 跨域不共享
- 具有存储空间限制
- 请求会自动携带cookie
简单实现:
A标签页:
setInterval(() => {
//加入定时器,让函数每一秒就调用一次,实现页面刷新
console.log("cookie",document.cookie)
}, 1000);
- 为什么使用setInterval?因为cookie本身没有回调事件监听cookie的变化,需要使用setInterval实现。
B标签页:
document.cookie = `100`
注意:
- 有同源共享策略限制,跨域不共享。
- 能够传输的数据太小(4k),不推荐使用。