- 通过
websocket
- 无跨域限制
- 需要服务端支持,成本高
- 通过
localStorage
同域通讯(推荐)同域
的A
和B
两个页面A
页面设置localStorage
B
页面可监听到localStorage
值的修改
- 通过
SharedWorker
通讯SharedWorker
是WebWorker
的一种WebWorker
可开启子进程执行JS
,但不能操作DOM
SharedWorker
可单独开启一个进程,用于同域页面通讯SharedWorker
兼容性不太好,调试不方便,IE11
不支持
localStorage通讯例子
<!-- 列表页 -->
<p>localStorage message - list page</p><script>// 监听storage事件window.addEventListener('storage', event => {console.info('key', event.key)console.info('value', event.newValue)})
</script>
<!-- 详情页 -->
<p>localStorage message - detail page</p><button id="btn1">修改标题</button><script>const btn1 = document.getElementById('btn1')btn1.addEventListener('click', () => {const newInfo = {id: 100,name: '标题' + Date.now()}localStorage.setItem('changeInfo', JSON.stringify(newInfo))})// localStorage 跨域不共享
</script>
SharedWorker通讯例子
本地调试的时候打开chrome隐私模式验证,如果没有收到消息,打开chrome://inspect/#workers
=> sharedWorkers
=> 点击inspect
<p>SharedWorker message - list page</p><script>const worker = new SharedWorker('./worker.js')worker.port.onmessage = e => console.info('list', e.data)
</script>
<p>SharedWorker message - detail page</p>
<button id="btn1">修改标题</button><script>const worker = new SharedWorker('./worker.js')const btn1 = document.getElementById('btn1')btn1.addEventListener('click', () => {console.log('clicked')worker.port.postMessage('detail go...')})
</script>
// worker.js/*** @description for SharedWorker*/const set = new Set()onconnect = event => {const port = event.ports[0]set.add(port)// 接收信息port.onmessage = e => {// 广播消息set.forEach(p => {if (p === port) return // 不给自己广播p.postMessage(e.data)})}// 发送信息port.postMessage('worker.js done')
}
如何实现网页和iframe之间的通讯 ?
- 使用
postMessage
通信 - 注意跨域的限制和判断,判断域名的合法性
演示
<!-- 首页 -->
<p>index page<button id="btn1">发送消息</button>
</p><iframe id="iframe1" src="./child.html"></iframe><script>document.getElementById('btn1').addEventListener('click', () => {console.info('index clicked')window.iframe1.contentWindow.postMessage('hello', '*') // * 没有域名限制})// 接收child的消息window.addEventListener('message', event => {console.info('origin', event.origin) // 来源的域名console.info('index received', event.data)})
</script>
<!-- 子页面 -->
<p>child page<button id="btn1">发送消息</button>
</p><script>document.getElementById('btn1').addEventListener('click', () => {console.info('child clicked')// child被嵌入到index页面,获取child的父页面window.parent.postMessage('world', '*') // * 没有域名限制})// 接收parent的消息window.addEventListener('message', event => {console.info('origin', event.origin) // 判断 origin 的合法性console.info('child received', event.data)})
</script>
效果