Call function on iframe parent window (window.top/window.parent) (规避跨源对象访问安全)

Call function on iframe parent window (window.top/window.parent) (circumvent cross-origin object access security)

有没有办法避免在页面(域 B) 尝试访问 window.top?

的属性

我想调用一个函数,即。 someFunc,属于域B,通过域A的iframe中的事件,在域B的上下文中。

示例:

a.com/index.html

<!DOCTYPE html>
<html>
  <body>
    <script>
      var someFunc = t => document.querySelector("#test").text = t;
    </script>
    <span id="test">This is some dummy text.</span>
    <iframe src="https://b.com/index.html"></iframe>
  </body>
</html>

b.com/index.html

<!DOCTYPE html>
<html>
  <body>
    <button id="btn">Test</button>
    <script>
      document.querySelector("#btn").addEventListener("click", (e) => {
        window.top.someFunc("This text has been changed through a cross-origin")
      });
    </script>
  </body>
</html>

此示例在 Firefox 上引发以下错误:
SecurityError: Permission denied to access property "someFunc" on cross-origin object

避免这种情况的正确方法是使用 Window.postMessage - 本质上,将消息从 iframe 发送到其父 window,如果它具有 [=12= 的事件侦听器], 可以做出相应的反应。

即:

a.com/index.html

<!DOCTYPE html>
<html>
  <body>
    <script>
      let someFunc = t => document.querySelector("#test").text = t;
      window.addEventListener("message", event => someFunc(e.data));
    </script>
    <span id="test">This is some dummy text.</span>
    <iframe src="https://b.com/index.html"></iframe>
  </body>
</html>

b.com/index.html

<!DOCTYPE html>
<html>
  <body>
    <button id="btn">Test</button>
    <script>
      document.querySelector("#btn")
        .addEventListener("click", event => {
          window.parent.postMessage("Changed text", "http://a.com");
        });
    </script>
  </body>
</html>