JavaScript新窗口与子窗口传值详解


在JavaScript中,新窗口(通常是通过`window.open()`打开的)与子窗口之间的通信主要通过几种方式实现,包括使用`window.opener`属性、`localStorage`/`sessionStorage`(对于同源策略下的窗口)、`postMessage`方法等。这里,我将详细介绍使用`postMessage`方法和`window.opener`属性进行窗口间通信的方法,因为它们是跨域和同源窗口间通信的常用且安全的方式。

### 1. 使用`postMessage`方法

`postMessage`方法允许来自不同源的窗口进行安全通信。你可以通过这个方法发送一个包含数据的消息到另一个窗口,而接收窗口可以监听`message`事件来接收这些消息。

**发送消息(父窗口)**:


// 假设子窗口的引用保存在变量childWindow中
var childWindow = window.open('http://example.com/child.html', '_blank');

// 发送消息到子窗口
childWindow.postMessage('Hello, child!', 'http://example.com'); // 注意:目标origin必须匹配

**接收消息(子窗口)**:

在子窗口的`child.html`中,你需要添加一个事件监听器来接收消息。


window.addEventListener('message', function(event) {
    // 检查event.origin是否是期望的来源
    if (event.origin !== 'http://your-parent-window-origin.com') {
        return; // 如果不是期望的来源,则忽略消息
    }

    console.log('Received message:', event.data);
    // 处理接收到的数据
});

### 2. 使用`window.opener`属性(仅限于父子窗口)

如果新窗口是由当前窗口打开的(即它们是父子关系),则子窗口可以通过`window.opener`属性访问父窗口。

**从子窗口向父窗口发送数据**:


// 子窗口中的代码
if (window.opener && !window.opener.closed) {
    window.opener.someFunctionInParentWindow('Hello from child!');
}

// 假设父窗口中有一个名为someFunctionInParentWindow的函数
// function someFunctionInParentWindow(data) {
//     console.log(data);
// }

注意:使用`window.opener`时,需要确保父窗口仍然打开且未关闭(`!window.opener.closed`)。

**从父窗口向子窗口发送数据**:

通常,你会在打开子窗口时保留一个对子窗口对象的引用,然后直接调用子窗口的方法或修改其属性。


// 父窗口中的代码
var childWindow = window.open('http://example.com/child.html', '_blank');

// 假设子窗口有一个名为receiveDataFromParent的函数
// 在子窗口的脚本中定义它
childWindow.receiveDataFromParent('Hello, child!');

但是,如果子窗口来自不同的源,则由于同源策略的限制,你不能直接调用子窗口的函数或修改其属性。在这种情况下,应使用`postMessage`方法。

希望这能帮助你理解JavaScript中窗口间通信的基本概念和方法。