一文搞懂window.postMessage和window.parent.postMessage

前言

在现代网页开发中,跨域通信是一个至关重要的方面,它允许来自不同域的不同网页或框架安全地相互交互。实现这一目标的一种流行机制是使用JavaScript中的postMessage API。在本文中,我们将深入探讨 window.postMessage 和 window.parent.postMessage 的概念,探索它们如何在网页应用程序中的不同上下文之间实现通信。

window.postMessage:窗口.postMessage

该 window.postMessage 方法是一种安全的方式,可以实现不同源(域)的两个窗口(或标签页)之间的通信。它允许一个窗口的脚本安全地向另一个窗口传递消息,即使它们来自不同的域。这对于在您的Web应用程序中嵌入第三方小部件、iframe或跨源通信特别有用。

js 复制代码
otherWindow.postMessage(message, targetOrigin, [transfer]);

参数

  • 要发送到另一个窗口的数据。它可以是一个字符串、一个对象,或者任何其他可JSON序列化的数据。
  • targetOrigin :指定目标窗口的来源。为了增强安全性,应将此参数设置为目标窗口的特定来源(例如,"example.com")。您也可以使用"*"来允许与任何来源的通信,但这样做安全性较低。
  • (可选):一个Transferable对象数组(例如ArrayBuffer、MessagePort),在发送到另一个窗口时应该转移而不是克隆。当处理大数据时,该参数对提高性能很有用。
js 复制代码
<!--origin1.html-->

<!DOCTYPE html>
<html>
<head>
  <title>Origin 1</title>
</head>
<body>
  <button onclick="sendMessage()">Send Message</button>

  <script>
    function sendMessage() {
      const otherWindow = window.open('https://origin2.com/origin2.html');
      const message = 'Hello from Origin 1!';
      const targetOrigin = 'https://origin2.com';
      otherWindow.postMessage(message, targetOrigin);
    }
  </script>
</body>
</html>
js 复制代码
<!--origin2.html-->

<!DOCTYPE html>
<html>
<head>
  <title>Origin 2</title>
</head>
<body>
  <script>
    window.addEventListener('message', receiveMessage, false);

    function receiveMessage(event) {
      if (event.origin === 'https://origin1.com') {
        alert('Received message: ' + event.data);
      }
    }
  </script>
</body>
</html>

在这个例子中,当在origin1.html中点击"发送消息"按钮时,它会打开一个新窗口,显示origin2.html并发送消息"来自Origin 1的问候!"。origin2.html窗口接收消息并显示一个警报,其中包含接收到的数据,但仅在安全目的下,原始来源匹配"origin1.com"时。

window.parent.postMessage:窗口.父级.发送消息

如果你正在寻找一个关于如何在网页应用程序中从一个iframe发送数据到其父窗口的答案,那么你来对地方了!

该 window.parent.postMessage 方法类似于 window.postMessage 方法,但它专门用于在嵌入的 iframe 中与其父窗口进行通信。

ini 复制代码
parent.postMessage(message, targetOrigin, [transfer]);

参数

  • 要发送到父窗口的数据。
  • targetOrigin :指定父窗口的来源。
  • transfer (可选):与 window.postMessage 一样,此参数允许在发送时传输数据而不是克隆。

考虑这样一个情景,一个 parent.html 文件嵌入了来自不同源的 iframe(child.html):

js 复制代码
<!--parent.html-->

<!DOCTYPE html>
<html>
<head>
  <title>Parent Window</title>
</head>
<body>
  <iframe src="https://origin2.com/child.html"></iframe>
</body>
</html>
js 复制代码
<!--child.html-->

<!DOCTYPE html>
<html>
<head>
  <title>Child Window</title>
</head>
<body>
  <button onclick="sendMessage()">Send Message to Parent</button>

  <script>
    function sendMessage() {
      const message = 'Hello from Child Window!';
      parent.postMessage(message, 'https://origin1.com');
    }
  </script>
</body>
</html>

在这个例子中,当在child.html中点击"发送消息给父窗口"按钮时,它会向其父窗口(origin1.html)发送消息"来自子窗口的问候!"。parent.html窗口接收到消息后可以相应地处理它。

我可以使用 window.parent.postMessage 发送复杂数据,比如对象或数组吗?

是的,您可以使用 window.parent.postMessage 发送复杂数据,比如对象或数组。该方法支持 JSON 可序列化的数据,因此您可以将 JavaScript 对象和数组作为消息内容传递。只需确保数据可以在 iframe 和父窗口之间安全地序列化和反序列化。

相关推荐
flash俊杰14 分钟前
屏幕感知双通道:截图之外,为什么还要一份 UIA 控件清单
前端
熟的生菜15 分钟前
从零造一个腱绳驱动灵巧手——仿真器篇3:VTK 渲染与 3D 交互——看得见、点得着、转得动
前端
ZhengEnCi28 分钟前
工科读研真的能抗学历贬值吗:研究生 vs 本科生的真实差距与选型判断
面试
Henry-SAP1 小时前
SAP PP中的核心业务流程——离散制造、重复制造、流程制造三大模式解析
前端·数据库·人工智能·制造
徐小夕2 小时前
下载量超 30 万的开源智能体 Prime Agent:它把自己从 TypeScript 重写成了 Rust
前端·vue.js·github
Zhao-Jichao2 小时前
AI Prompting for Everyone 课程笔记 - P20 实验与期末项目 Lab and Final Project
前端·人工智能·笔记
Rain的Java大神之路2 小时前
国家数据集团校招、社招都开了:总部雄安,这些技术岗值得认真看看
java·后端·面试
Moment2 小时前
为什么这么多 Agent Harness 都选择 TypeScript
前端·后端·面试
toooooop82 小时前
CRMEB 故障排查笔记:安全网关只放行 GET/POST 怎么办
前端·javascript·vue.js·thinkphp6·crmeb
软件技术NINI2 小时前
基于SpringBoot和Vue的项目评审系统
javascript·vue.js·spring boot·后端·spring·毕业设计·毕设