单击按钮后关闭使用 window.open() 打开的 window

Close a window opened with window.open() after clicking a button

我这里有一个简单的案例:

我用window.open('http://remoteserver.com/success')在浏览器中打开一个window是这样的:

const win = window.open('http://remoteserver.com/success')

现在远程服务器发送一个 HTML 像这样:

<!DOCTYPE html>
<html lang="en">
  <body>
  <div class="row text-center" style="margin-top:50px">
    Success!
    <button type="button" class="btn btn-primary" onclick="closeWindow()">Go Back</button>
  </div>
  </body>
  <script >
  function closeWindow(e)
  {
    this.close()
    console.log(e);
  }
  </script>
</html>

现在,当用户点击 "go back" 按钮时,它会显示一条警告,指出 windows 只能由打开它的脚本关闭!

如何关闭这样的window?

您可以使用 window.postMessage() 向 post 家长 window 发送消息。在父 window 中,侦听新消息并在收到来自正确来源的包含正确数据的消息时关闭 window。

const popup = window.open('http://example.com/success')
window.addEventListener('message', event => {
  // Only accept messages from http://example.com.
  if (event.origin === 'http://example.com') {
    if (event.data === 'close') popup.close()
  }
})

HTML 文件:

<!DOCTYPE html>
<html lang="en">
  <body>
  <div class="row text-center" style="margin-top:50px">
    Success!
    <button type="button" class="btn btn-primary">Go Back</button>
  </div>
  </body>
  <script>
    document.querySelector('button').addEventListener('click', () => {
      // Only send messages to http://example.com.
      window.opener.postMessage('close', 'http://example.com')
    })
  </script>
</html>

这是一项安全功能,因为脚本不应完全控制所有打开的 windows。从 window.close() 规范我们可以得到以下内容:

The close() method on Window objects should, if all the following conditions are met, close the browsing context A:

The corresponding browsing context A is script-closable.

The responsible browsing context specified by the incumbent settings object is familiar with the browsing context A.

The responsible browsing context specified by the incumbent settings object is allowed to navigate the browsing context A.

A browsing context is script-closable if it is an auxiliary browsing context that was created by a script (as opposed to by an action of the user), or if it is a top-level browsing context whose session history contains only one Document.

您可以使用的一种解决方案是 window.postMessage API (https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage),它可以安全地启用跨域通信。基本上你要做的是:

  1. 您的打开脚本保留对打开的 window 的引用并为传入消息注册侦听器

  2. 打开的window的html在用户点击按钮后立即发送一个事件

  3. 打开 window 的脚本实际上在其侦听器方法中关闭了 window

在代码中:

打开脚本

var popup = window.open("http://remoteserver.com/success", "_blank");
var receiveMessage = function (event) {
    if (event.data.indexOf("SUCCESS") !== -1 && event.origin.indexOf('.remoteserver.com') !== -1) {
        popup.close();
    }
};

window.removeEventListener("message", receiveMessage);

打开了window脚本

<!DOCTYPE html>
<html lang="en">
<body>
<div class="row text-center" style="margin-top:50px">
    Success!
    <button type="button" class="btn btn-primary" onclick="closeWindow()">Go Back</button>
</div>
</body>
<script >
function closeWindow(e)
{
    window.parent.postMessage('SUCCESS', 'http://localserver.com')
    console.log(e);
}
</script>
</html>