无法使用postmessage访问跨域的iframe元素

Can not access iframe elements of cross domain using postmessage

我正在处理两个网站。我在一个网站项目中有一个带有母版页的 aspx 页面。我想在我的第二个网站中的另一个页面中将此页面用作 iframe,该页面也有母版页。当我这样做时,我得到了两个母版页,而我想从我的 Iframe 中删除母版页。

简而言之,如何从不同域的顶部 window 访问子 window 的元素?

首先,我尝试从页面 preInit 事件中的代码后面替换母版页,但我无法获得子页面的母版页。所以这对我不起作用。

第二种解决方案我试图将其从 jquery 中删除。在这里,我无法访问 iframe 的内容,因为它来自不同的域。所以,我使用了 Post-message 但仍然出现同样的问题。这是我的代码,我试过了。

在父页面中:

window.addEventListener("message", function (e) {
        alert(e.origin);
        if (e.origin !== 'http://localhost:xxxxx') {
            return;
        }
        alert(e.data);

    }, false);

在 iframe 页面中:

$(document).ready(function () {
       window.parent.postMessage("I am loaded", "*");
    });

我在邮件中收到了消息,但仍然无法访问 iframe 中的元素(e.source 在我的例子中)。

请帮忙!

首先:永远不要使用 alert

相反,使用 console.log,它自 2010 年以来一直是首选,引入它是因为除了无法记录字符串以外的任何内容(因此将数据强制转换为字符串,导致诸如 [Object: object]),alert函数阻塞了整个JS线程。它是过去时代的遗留 JS。它在 2010 年以来编写的任何代码中都没有位置,更不用说你今天编写的任何代码了。

至于你的问题,你不想 post 发消息给 window.parent,你需要做一些特征检测来发现你的 post 目标应该在您的 iframe 脚本中:

const target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);
if (target) {
  target.postMessage({ ... }, "*");
} else {
  console.error("no valid postMessage target... what browser is this?");
}

此外,jQuery 在这里用处不大,只需使用 defer 加载脚本并编写代码而无需任何 window.addEventlistener('loaded'....$.ready(....) 作为 defer关键字将take care of that for you(如果你不熟悉defer,自2012年以来每个主流浏览器都支持它,所以不用担心IE不支持它,例如)。

Simply, How can I access child window's element from top window with different domain?

你不能。文档之间只能post消息

因此,如果您想对另一页上的某个元素执行某些操作,则需要:

  • 发送一条消息,要求对该元素执行该操作
  • 编写代码来侦听该消息并执行该操作

例如

父页面

<!DOCTYPE html>
<meta charset="utf=8">
<title>Parent</title>
<script>
    addEventListener(
      "message",
      function(e) {
        if (e.origin !== "http://localhost:8080") {
          return;
        }
        if (e.data.message === "Ready and waiting") {
            console.log("Message recieved from child iframe");
            // Now we know the document has loaded into the frame and is ready to recieve messages. 
            document.querySelector("iframe").contentWindow.postMessage({
                message: "Remove",
                selector: "#b"
            },
            "http://localhost:8080")
        }
      }
    );
</script>
<iframe src="http://localhost:8080/frame.html"></iframe>

带框的页面

<!DOCTYPE html>
<meta charset="utf=8">
<title>Child</title>
<div id="a">A</div>
<div id="b">B</div>
<div id="c">C</div>
<script>
    window.parent.postMessage({ message: "Ready and waiting" }, "http://localhost:8081");

    addEventListener(
        "message",
        function(e) {
            if (e.origin !== "http://localhost:8081") {
                return;
            }
            console.log("Message recieved from child iframe", e.data);
            if (e.data.message === "Remove") {
                document.querySelector(e.data.selector).remove();
            }
        }
    );
</script>