window.postMessage()实现往iframe页面里面发送消息

本文介绍如何使用window.postMessage()方法实现跨域安全通信,详细解释了其基本语法及参数,包括targetWindow、message、targetOrigin和transfer。并通过示例展示了发送与接收消息的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

window.postMessage()方法可以安全地实现Window对象之间的跨域通信。例如,在一个页面和它生成的弹出窗口之间,或者是页面和嵌入其中的iframe之间。

通常情况下,不同页面上的脚本允许彼此访问,当且仅当它们源自的页面共享相同的协议,端口号和主机(也称为“同源策略”)。window.postMessage()提供了一个受控的机制来安全地规避这个限制(如果使用得当的话)。

一般来说,一个窗口可以获得对另一个窗口的引用(例如,通过targetWindow=window.opener),然后使用targetWindow.postMessage()在其上派发MessageEvent。接收窗口随后可根据需要自行处理此事件。传递给window.postMessage()的参数通过事件对象暴露给接收窗口。

发送消息的基本语法:

targetWindow.postMessage(message, targetOrigin, [transfer]);

targetWindow

targetWindow就是接收消息的窗口的引用。 获得该引用的方法包括:

  • Window.open
  • Window.opener
  • HTMLIFrameElement.contentWindow
  • Window.parent
  • Window.frames +索引值

message

message就是要发送到目标窗口的消息。 数据使用结构化克隆算法进行序列化。 这意味着我们可以将各种各样的数据对象安全地传递到目标窗口,而无需自己对其进行序列化。

targetOrigin

targetOrigin就是指定目标窗口的来源,必须与消息发送目标相一致,可以是字符串“*”或URI。 *表示任何目标窗口都可接收,为安全起见,请一定要明确提定接收方的URI。

transfer

transfer是可选参数

event对象有三个属性,分别是origin,data和source。event.data表示接收到的消息;event.origin表示postMessage的发送来源,包括协议,域名和端口;event.source表示发送消息的窗口对象的引用; 我们可以用这个引用来建立两个不同来源的窗口之间的双向通信。


 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>发送消息页面</title>
</head>
<body>
 <iframe src="./receive.html" id="receiver" width="600" height="500"></iframe>
 <button id="btn">发送消息</button> 
</body>
<script>
  document.querySelector('#btn').onclick = function () {
    document.getElementById('receiver').contentWindow.postMessage("Hello!", "http://localhost:9999");
    alert('我发送信息给子窗口了!');
  }
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>接受消息页面</title>
</head>
<body>
  <h1>我是接受参数的页面</h1>
</body>
<script>
  window.onload = function () {
    var NUM = 0;
    window.addEventListener('message', function (e) {
      console.log(e);
      let h1 = document.createElement('h1');
      h1.innerHTML = '第' + (NUM++) + '条信息,' + e.data;
      document.body.appendChild(h1);
    });
  }
</script>
</html>

运行结果:

### window.opener.postMessage 的使用方法 `window.opener.postMessage()` 是一种实现跨窗口通信的方法,适用于通过 `window.open()` 打开的子窗口与父窗口之间的交互。该方法允许两个窗口之间传递数据,即使它们来自不同的源(跨域)也可以安全地通信。 #### 使用语法 ```javascript window.opener.postMessage(message, targetOrigin, [transfer]); ``` - **message**:需要发送消息,类型为字符串。 - **targetOrigin**:目标窗口的源(协议 + 主机 + 端口),可以是具体的 URI 或者使用 `*` 表示不限制源。 - **transfer**(可选):一个可转移对象(如 `ArrayBuffer`、`MessagePort` 等)的数组,这些对象的所有权将被转移到目标窗口。 #### 示例代码 ##### 父窗口代码 父窗口通过 `window.open()` 打开一个新的子窗口,并使用 `postMessage()` 发送消息。 ```html <!-- parent.html --> <!DOCTYPE html> <html> <head> <title>Parent Window</title> </head> <body> <button onclick="openChildWindow()">Open Child Window</button> <script> let childWindow; function openChildWindow() { childWindow = window.open('child.html', '_blank'); } function sendMessageToChild() { if (childWindow) { childWindow.postMessage("Hello from Parent", "*"); } } // 监听来自子窗口的消息 window.addEventListener("message", function(event) { console.log("Received message from child:", event.data); }); </script> </body> </html> ``` ##### 子窗口代码 子窗口监听来自父窗口的消息,并可以通过 `window.opener.postMessage()` 回复消息。 ```html <!-- child.html --> <!DOCTYPE html> <html> <head> <title>Child Window</title> </head> <body> <h1>Child Window</h1> <script> // 监听来自父窗口的消息 window.addEventListener("message", function(event) { console.log("Received message from parent:", event.data); // 回复消息给父窗口 if (event.origin !== "http://example.com") { // 替换为实际的父窗口源 return; } window.opener.postMessage("Hello back from Child", "*"); }); </script> </body> </html> ``` #### 注意事项 - **安全性**:建议在 `targetOrigin` 参数中指定明确的源,而不是使用 `*`,以防止敏感信息泄露[^2]。 - **跨域限制**:虽然 `postMessage()` 支持跨域通信,但必须确保两个窗口之间存在直接的引用关系(如通过 `window.open()` 或 `iframe`)[^4]。 - **兼容性**:现代浏览器普遍支持 `window.postMessage()`,但在旧版浏览器中可能存在兼容性问题。 --- ### window.opener 的作用 `window.opener` 返回对打开当前窗口的父窗口的引用。如果当前窗口是由另一个窗口通过 `window.open()` 创建的,则可以通过 `window.opener` 访问父窗口的 `window` 对象。这使得子窗口能够向父窗口发送消息或获取其属性[^3]。 --- ### 完整流程说明 1. 父窗口通过 `window.open()` 打开子窗口。 2. 父窗口调用 `childWindow.postMessage()` 向子窗口发送消息。 3. 子窗口通过 `window.addEventListener("message", ...)` 接收消息。 4. 子窗口通过 `window.opener.postMessage()` 回复消息给父窗口。 5. 父窗口通过 `window.addEventListener("message", ...)` 接收子窗口的回复。 这种方式实现了双向通信,并且支持跨域场景下的数据交换。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值