跨页面通信实现方案

同源页面

广播模式,页面将消息通知给一个中转,中转再通知给各个页面。中转可以是一个 BroadCast Channel 实例、一个 Service Worker 或是 LocalStorage。

BrocastChannel

BrocastChannel可以实现同源下浏览器不同窗口,tab页,frame或frame下的浏览器上下文之间的通信。

// a页面
var bc = new BroadcastChannel('qwer')
bc.postMessage('发送数据')

// b页面
var bc = new BroadcastChannel('qwer')
bc.onmessage = function(e) {
  console.log(e)
}
/** 消息发送后,所有连接到该频道的 BrocastChannel对象上都会触发 meaasge事件,
该事件没有默认行为,可以使用`onmessage`事件处理程序来定义一个函数处理消息
**/

LocalStorage

LocalStorage是前端常用的本地存储,当LocalStorage变化是,会触发storage事件,发送消息时,将消息写入LocalStorage中,然后在各个页面中,通过监听storage事件即可收到通知。

// a页面
window.addEventListener('storage', function(e) {
  console.log(e)
})

// b页面
localStorage.setItem('qwer', 10000)

Service Worker

Service Worker与页面通信
前端跨页面通信的方法

共享存储 + 长轮询模式

SharedWorker

SharedWorker可以开启后台线程运行脚本,并且多个页面之间可以共享,通过port.postMessage发送消息,通过监听message事件实现。如果a页面向后台线程发送消息,后台线程触发message事件后再发送的消息只能被a页面接收,即SharedWorker可以一个线程处理不同的页面逻辑,然后将结果返回对应的页面

  • 根据以上原理,在SharedWorker脚本中设置共享数据以实现页面间的通信
//可以在chrome://inspect中对子线程中的代码进行调试
onconnect = function(e) {
  console.log(e)
  const port = e.ports[0]
  port.onmessage = function(event){
    console.log(event)
    port.postMessage(event.data)
  }
}

页面1中的代码

var sharedWorker = new SharedWorker('./shareWorker.js', 'cpc')
sharedWorker.port.postMessage({
  a: 1,
  b: 2
})
 // 发送数据,此时共享数据的值已经被更改

页面2中的代码

var sharedWorker = new SharedWorker('./shareWorker.js', 'cpc')
sharedWorker.port.postMessage({ get: true })

// 如果需要实时更新的话,可能需要`setInterval`进行轮询

indexDB方案

前端跨页面通信方法

非同源页面

非同源页面之间的通信通过iframe实现。各个需要通信的页面加载应该相同的iframe,这些iframe之间使用的是同一个url,属于同源,可以相互通信,接收到消息后postMessage到主页面即可。

// iframe中的代码
const bc = new BroadcastChannel('cpc')
window.addEventListener('message', function(e) {
  console.log(e)
  if(e.origin === 'https://magazine.heytapimage.com' || e.origin === 'https://magazine-static-cpc.heytapimage.com') {
    bc.postMessage(e.data)
    console.log('bc postMessage')
  }
})
bc.onmessage = function(e) {
  window.parent.postMessage(e.data, 'https://magazine.heytapimage.com') //  支持传入指定域名或*
  console.log('bc receiveMessage')
}

a页面的代码



b页面的代码



你可能感兴趣的:(跨页面通信实现方案)