跨页面通信

Posted by CodingWithAlice on June 29, 2021

跨页面通信

两个页面之间的通信会涉及到同源策略的限制,所以按照是否满足同源策略的限制分成两大部分来看。

『同源页面通信』:

  • 1、广播式通信 - 监听同一频道 BroadcastChannel
    • 『核心方法:频道.postMessage(‘a’) + 频道.onmessage = (e)=>{}』
  • 2、localStorage - 只响应非当前页面的修改
    • 『核心方法:localStorage.setItem(key,value) + window.onstorage = (e)=>{}』

『非同源页面通信』:

  • 1、window.open + postMessage(h5 API)
    • 『核心方法:win=window.open(url) + win.postMessage(‘a’) + window.onmessage = (e)=>{}』
  • 『2、通过 iframe 转换成同源页面通信』
    • origin设置同源

一、同源页面间的通信

1、广播式通信 BroadcastChannel

核心要点:所有页面都监听同一频道的消息,其中某一个页面通过它发送的消息就会被其他所有页面收到

注意:两个页面都需要对同一个频道实例化

// 页面1 - 实例化广播,并监听 message
let broad = new BroadcastChannel('qiu');
broad.onmessage = (e) => {
    console.log('e=', e); // MessageEvent
}
// 页面2 - 同一个广播,发送消息 -> 触发页面1的监听函数
const board = new BroadcastChannel('qiu');
board.postMessage('我想吃冻干');

image-20241101135445305

2、localStorage

localstorage 是浏览器 多个标签共用 的存储空间(同源策略 - 共享渲染进程)

sessionStorage 是会话级的存储空间,每个标签页都是单独的,互不干扰

核心要点:

  • 特点1:onstorage - 针对 非当前页面localStorage 进行修改时才会触发,当前页面修改 localStorage 不会触发监听函数
  • 特点2:在对原有的数据的值进行 修改时才会触发
// 页面1 - 监听 localstroage 的变化
window.onstorage = (e) => {
    console.log('A 页面监听:', e);
}
// 页面2 - 改变 localStorage -> 触发监听事件
localStorage.setItem('qiu', {time: +(new Date())});

image-20241101141756915

二、非同源页面间的通信

1、window.open + postMessage(h5 API)

核心:

  • postMessage是 HTML5 中提供的一种在不同源的窗口之间进行安全通信的方法。它允许一个窗口向另一个窗口发送消息,无论这两个窗口是否同源。
  • 发送消息的窗口可以指定接收消息的窗口的源(origin),确保消息只被目标窗口接收,提高了安全性
// 页面A
const targetWindow = window.open('http://d.com', 'targetWindow');
targetWindow.postMessage('这是来自页面 A 的消息', 'http://d.com');
// 页面B
window.addEventListener('message', function (e) {
  if (event.origin === 'http://d.com') {
    console.log('页面 B 收到的消息:', e.data);
  }
});

2、通过 iframe 转换成同源页面通信

核心要点:由于 iframe 与父页面间可以通过 指定 origin 来忽略同源限制,因此可以在每个页面中嵌入同一个 iframe

这些 iframe 由于使用的是一个 url,因此属于同源页面,其通信方式可以复用上面第一部分提到的各种方式