SkyBlog

浏览器跨窗口共享数据

这篇文章发布于 2025年01月24日,星期五,06:12阅读 ? 次,0 条评论

同源

仅能同源窗口之间传递数据

LocalStorage / SessionStorage

看起来不是什么正经方案,唯一想到的用途是页面明暗主题切换

window.localStorage.setItem('key', 'hello world')
window.addEventListener('storage', event => {
  console.log(event)
})

MessagePort

点对点双向通讯,MessagePort 是可转移对象

const { port1, port2 } = new MessageChannel()
 
const worker = new Worker('worker.js')
worker.postMessage({ port: port1 }, [port1])
 
port2.onmessage = event => {
  console.log('Received from worker:', event.data)
}
 
port2.postMessage('hello world')
self.onmessage = event => {
  const { port } = event.data
 
  port.onmessage = event => {
    console.log('Received from main thread:', event.data)
  }
 
  port.postMessage('hello world')
}

BroadcastChannel

多个窗口或标签页之间的广播通信

const channel = new BroadcastChannel('name')
channel.postMessage('hello world')
const channel = new BroadcastChannel('name')
channel.onmessage = event => {
  console.log(event.data)
}

SharedWorker

多个窗口或标签页共享同一个后台线程

const worker = new SharedWorker('worker.js')
 
worker.port.onmessage = event => {
  console.log('Received from worker:', event.data)
}
 
worker.port.postMessage('hello world')
const ports = []
 
self.onconnect = event => {
  const port = event.ports[0]
  ports.push(port)
 
  port.onmessage = event => {
    console.log(event.data)
  }
 
  port.postMessage('hello world')
}

不同源

不同源窗口之间也能传递数据

PostMessage

window.postMessage('hello world', '*')
window.addEventListener('message', event => {
  console.log(event.data)
})