我们在开发过程中,偶尔会遇到特殊的场景需求,用户打开俩个标签页,分别操作,并且数据要实时,这时候我们就要用到跨标签通信来解决类似的需求,总结了几种方案(同域):
一、localStorage
:
我们可以监听 localStorage
改变,接着实现想要的逻辑,禁止重复发送,不生效
发送端:
// 发送一个数据
localStorage.setItem('username', '张三')
监听端:
// 监听 localstorage 变化
window.addEventListener('storage', event => {
console.log(event)
})
可以看到,接收端的 localStorage
值:
二、webSocket
:
这种方式工作中常用,这里忽略跳过
三、SharedWorker
:
与 webSocket
类似,需要有一个类似 socket 服务的终端
发送端:
<button id="btn">发送消息</button>
<script>
// 创建共享线程
let worker = new SharedWorker('worker.js')
// 发送消息
document.getElementById('btn').addEventListener('click', e => {
worker.port.postMessage(Math.random()*1000)
})
// 接收消息
worker.port.onmessage = e => {
console.log(e.data)
}
// 启动线程端口
worker.port.start()
</script>
终端:
onconnect = (e) => {
let port = e.ports[0];
port.postMessage('connect')
port.addEventListener('message', e => {
port.postMessage(`handler data:${parseInt(e.data)}`)
})
port.start()
};
通过 chrome://inspect/#workers
可查看终端的输出,点击 inspect
查看,可以看到终端处理数据后返回,并且支持群发,感兴趣的小伙伴可以去研究
附兼容性表:
四、postMessage
:
发送端:
<button id="btn">发送消息</button>
<script>
let device = window.open('http://localhost:63342/signal_communication/postMessage/receive.html')
document.getElementById('btn').addEventListener('click', event => {
device.postMessage('发送一条消息')
})
</script>
接收端:
<script>
window.addEventListener('message', event => {
console.log(event)
})
</script>
五、BroadcastChannel
:
发送端:
<button id="btn">发送消息</button>
<script>
let device = new BroadcastChannel('username')
document.getElementById('btn').addEventListener('click', event => {
device.postMessage('张三')
})
</script>
接收端:
<script>
let device = new BroadcastChannel('username')
device.onmessage = event => {
console.log(event)
}
</script>
六、‘cookie + setInterval’:
这种就不说了,定时器轮询即可