Cross-Origin-Opener-Policy 和 window.open 在跨源 iframe 中返回 null,即使它打开成功

问题描述 投票:0回答:1

我有一个案例

  • Cross-Origin-Opener-Policy 设置为同源
  • 有跨域iframe...
  • ...在 iframe 中,我使用
    window.open
  • 打开另一个域上页面的弹出窗口/选项卡

那么即使选项卡成功打开,

window.open
的返回值为
null

例如如果

  • 我将以下内容保存在
    main.py
  • 安装fastapi,例如通过
    pip install fastapi
  • 运行
    uvicorn main:app --reload --port 8000
    uvicorn main:app --reload --port 8001
  • 访问http://localhost:8000/
  • 单击“打开”按钮

然后会打开一个新选项卡,显示 Google 主页,但我会在原始选项卡的控制台中看到

null

from typing import Union

from fastapi import FastAPI, Response
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
def read_root(response: Response):
    response.headers["Cross-Origin-Opener-Policy"] = "same-origin"
    return '''
        <iframe src="http://localhost:8001/iframe"></iframe>
    '''

@app.get("/iframe", response_class=HTMLResponse)
def read_iframe(response: Response):
    response.headers["Cross-Origin-Opener-Policy"] = "same-origin"
    return '''
        <button id="button">Open</button>
        <script>
            document.getElementById("button").addEventListener("click", () => {
                const w = window.open('https://www.google.com/', "_blank");
                console.log(w);
            });
        </script>
    '''

但是,如果我通过转到

http://localhost:8001/iframe
直接访问 iframe 并执行相同的操作,我会在控制台中看到似乎是 Window(/Window 代理?)对象。

或者:如果我使 iframe 与父页面位于同一域中,我还会在控制台中看到一个 Window/Window 代理对象。

或者:如果我将

same-origin
更改为
same-origin-allow-popups
,我还会在控制台中看到一个 Window/Window 代理对象。

为什么在跨源 iframe 且 Cross-Origin-Opener-Policy 设置为同源的情况下

window.open
返回
null
?在 https://developer.mozilla.org/en-US/docs/Web/API/Window/open 它说

如果浏览器无法打开新的浏览上下文,例如因为它被浏览器弹出窗口阻止程序阻止,则返回 null。

但是它确实打开了浏览上下文......

我想了解的原因:我在一个网站上有类似的设置,我正在

Cross-Origin-Opener-Policy: same-site
Cross-Origin-Opener-Policy: same-site-allow-popups
之间做出决定。所以,我需要了解它的作用。但是,window.open 的行为。取决于它是否在跨域 iframe 中,这稍微阻碍了这种理解

javascript google-chrome security iframe cross-origin-opener-policy
1个回答
0
投票

为什么在 Cross-Origin-Opener-Policy 设置为同源的跨源 iframe 的情况下,window.open 返回 null?

它在规格中。在这种情况下,它会使

window.open
的行为就像您将
noopener
传递给它一样,这反过来又使 window.open 返回 null。

更详细地,来自选择可导航的规则

  1. 如果 currentDocument 的跨源开启策略的值为“same-origin”或“same-origin-plus-COEP”,并且 currentDocument 的源与 currentDocument 的相关设置对象的顶级源不是同源,则:
    1. 将 noopener 设置为 true。
    2. 将名称设置为“_blank”。
    3. 将 windowType 设置为“new with no opener”。

然后从 7.2.2.1 打开和关闭窗口,当它描述 window.open 的作用时

  1. 如果 noopener 为 true 或 windowType 为“new with no opener”,则返回 null。

您还可以看到

window.open
noopener
的行为方式 - 不涉及 COOP 且不涉及 iframe - 它返回 null,就像本问题的情况一样。

from typing import Union

from fastapi import FastAPI, Response
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
def read_root(response: Response):
    return '''
        <button id="button">Open</button>
        <script>
            document.getElementById("button").addEventListener("click", () => {
                const w = window.open('https://www.google.com/', "_blank", "noopener");
                console.log(w);
            });
        </script>
    '''
© www.soinside.com 2019 - 2024. All rights reserved.