繁体   English   中英

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

[英]Can not access iframe elements of cross domain using postmessage

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

简单地说,如何从具有不同域的顶部窗口访问子窗口的元素?

首先,我尝试从页面 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", "*");
    });

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

请帮忙!

第一:永远不要使用alert

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

至于你的问题,你不想向 window.parent 发送消息,你需要做一些功能检测来发现你的发布目标应该在你的 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关键字将处理对你来说(如果你不熟悉defer ,自 2012 年以来,每个主要浏览器都支持它,所以不必担心 IE 不支持它,例如)。

简单地说,如何从具有不同域的顶部窗口访问子窗口的元素?

你不能。 您只能在文档之间发布消息

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

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

例如

父页面

<!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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM