Skip to content

浏览器跨窗口通信

最近做需求遇到的小功能: 从A页面新开个窗口打开B页面,B页面完成一系列操作后,需要自动关闭B页面,然后A页面完成一个刷新的动作。

理下逻辑:

1、A 页面打开 B页面,A页面可以拿到B页面的window

js
const newWindow= window.open(B)

2、B页面可以通过window.opener.postMessage向A页面发消息

js
window.opener.postMessage('submitSuccess', window.location.origin);

3、A页面通过window.addEventListener监听B页面的消息然后刷新

js
window.addEventListener('message', (event) => {
if (event.data === 'submitSuccess') {
console.log('监听到B消息执行下一步')
Freshpage();
}
})

如果B页面中通过微前端嵌入C页面,C页面通过window.parent.postMessage()向B页面发送消息

js
window.parent.postMessage('submitSuccess', window.location.origin)

window.parent.postMessage('submitSuccess', window.location.origin)通常在以下场景中使用: 一、跨域通信场景

  1. Iframe 与父窗口通信
  • 当网页中包含一个 iframe,并且 iframe 中的内容与父窗口来自不同的源(域名、协议、端口不同)时,可以使用这种方式向父窗口传递消息。
  • 例如,在一个在线文档编辑系统中,文档编辑页面可能以 iframe 的形式嵌入在主页面中。当用户在文档编辑页面完成提交操作后,可以使用这个方法向主页面发送一个“提交成功”的消息,以便主页面进行相应的状态更新或其他操作。
  1. 跨窗口通信
  • 有时候可能会有多个窗口同时打开,并且这些窗口之间需要进行通信。在这种情况下,可以使用postMessage方法在不同窗口之间传递消息。
  • 比如,一个在线协作工具可能同时打开了多个窗口用于不同的任务,当一个窗口中的操作完成后,可以向其他相关窗口发送消息以同步状态。 二、Web 组件通信场景
  1. 自定义 Web 组件内部与外部通信
  • 开发自定义 Web 组件时,组件内部的逻辑可能需要向包含该组件的页面传递消息。
  • 例如,一个自定义的表单组件,当表单提交成功后,可以通过这种方式向使用该组件的页面发送一个提交成功的消息,以便页面进行后续处理,如显示成功提示、更新页面状态等。
  1. 多个独立开发的 Web 组件之间通信
  • 在复杂的 Web 应用中,可能会使用多个独立开发的 Web 组件,这些组件之间有时需要进行通信。
  • 比如,一个电商网站的购物车组件和结算组件可能需要进行交互,当购物车中的商品提交成功后,购物车组件可以使用postMessage向结算组件发送消息,以便结算组件更新订单总价等信息。

window.opener.postMessage()主要适用于以下场景: 一、跨页面通信场景

  1. 由父页面打开子页面并通信:
  • 当一个网页(父页面)通过 window.open() 方法打开另一个网页(子页面)时,可以使用 window.opener.postMessage() 实现从子页面向父页面传递信息。
  • 例如,在一个在线购物网站中,父页面可能打开一个支付页面作为子页面。当支付成功后,子页面可以使用这个方法向父页面发送支付成功的消息,以便父页面更新订单状态或显示成功提示。
  1. 多窗口协作场景:
  • 在一些复杂的应用中,可能需要同时打开多个窗口进行协作。通过 window.opener.postMessage() 可以在不同窗口之间传递消息,实现数据同步或协调操作。
  • 比如,一个设计软件可能同时打开多个编辑窗口,当一个窗口中的操作影响到其他窗口时,可以使用这个方法进行通知。 二、安全的跨源通信场景
  1. 不同源页面间通信:
  • 由于 postMessage 可以进行安全的跨源通信,所以在父页面和子页面来自不同源(不同域名、协议或端口)的情况下,window.opener.postMessage() 仍然可以有效地传递消息。
  • 例如,一个企业内部的不同系统可能需要在浏览器中进行交互,即使它们运行在不同的域名下,也可以通过这种方式进行安全的通信。
  1. 防止跨站脚本攻击(XSS):
  • postMessage 提供了一种安全的通信机制,可以避免一些常见的安全漏洞,如 XSS 攻击。通过验证消息的来源,可以确保只接收来自可信窗口的消息。
  • 比如,在接收 postMessage 发送的消息时,可以检查 event.origin,确保消息来自预期的源,从而防止恶意页面发送虚假消息进行攻击。

window.opener.postMessage()window.parent.postMessage()主要有以下区别:

一、作用对象不同

  1. window.opener
  • 通常用于在通过window.open()打开新窗口后,新窗口向打开它的窗口(即父窗口)发送消息。
  • 例如,页面 A 使用window.open()打开了页面 B,在页面 B 中可以使用window.opener.postMessage()向页面 A 发送消息。
  • 如果页面 A 被关闭或者没有通过window.open()打开的页面使用window.opener会返回null
  1. window.parent
  • 主要用于在一个框架集(frameset)或者一个页面中包含iframe的情况下,子框架向父框架发送消息。
  • 比如,在一个包含多个iframe的页面中,某个iframe内的代码可以使用window.parent.postMessage()向包含它的页面发送消息。

二、适用场景不同

  1. window.opener.postMessage()
  • 只适用于明确知道两个页面之间是通过window.open()打开关系的场景。
  • 常用于在新打开的窗口完成某些操作后,通知打开它的窗口进行相应的处理。
  1. window.parent.postMessage()
  • 更适用于页面结构中存在嵌套关系,如框架集或iframe的场景。
  • 例如在一个复杂的 Web 应用中,不同部分的功能可能分别放在不同的iframe中,通过这种方式进行通信可以实现各部分之间的协调工作。

Copyright © 2024-present LofiSu