简体   繁体   中英

Can not access iframe elements of cross domain using postmessage

I am working with two web sites. I have one aspx page with master page in one web site project. I want to use this page as an iframe in my second web site within another page which also has master page. When I do this, I am getting both master pages, while I want to remove the master page from my Iframe.

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

First I tried to replace master page from code behind on page preInit event but there I can't get child page's master page. So this didn't work for me.

Second solution I tried to remove it from jquery. Here, I am not able to access content of iframe since its from different domain. So, I used Post-message but still the same issue occurs. Here is my code, I tried.

In Parent Page:

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

    }, false);

In Iframe Page:

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

I am getting message in my postmessage but still can't access elements (e.source in my case) inside iframe.

Please help!

First: don't use alert , ever.

Instead, use console.log , it's been the preferred choice since 2010, and was introduced because aside from not being able to log anything except strings (and so coerces data to string, leading to nonsense things like [Object: object] ), the alert function blocks the entire JS thread. It's legacy JS from a bygone era. It has no place in any code written since 2010, let alone any you write today.

As for your problem, you don't want to postmessage to window.parent, you'll want to do a bit of feature detecting to discover what your post target should be in your iframe's script:

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?");
}

Also, not much use for jQuery here, just load your scripts with defer and write your code without any window.addEventlistener('loaded'.... or $.ready(....) as the defer keyword will take care of that for you (if you're unfamiliar with defer , it's been supported by every major browser since 2012, so no need to worry about IE not supporting it, for instance).

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

You can't. You can only post messages between the documents.

So if you want to do something with an element on the other page then you need:

  • Send a message asking for that thing to be done to that element
  • Write code to listen for that message and do that thing

For example

Parent page

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

Framed page

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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