Невозможно получить доступ к элементам iframe кросс-домена, используя postmessage - PullRequest
0 голосов
/ 17 января 2020

Я работаю с двумя веб-сайтами. У меня есть одна страница 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", "*");
    });

Я получаю сообщение в своем почтовом сообщении, но все еще могу нет доступа к элементам (e.source в моем случае) внутри iframe.

Пожалуйста, помогите!

Ответы [ 2 ]

0 голосов
/ 17 января 2020

Проще, как я могу получить доступ к элементу дочернего окна из верхнего окна с другим доменом?

Вы не можете. Между документами можно публиковать только сообщений .

Так что, если вы хотите что-то сделать с элементом на другой странице, вам нужно:

  • Отправить сообщение с просьбой сделать эту вещь с этим элементом
  • Напишите код для прослушивания этого сообщения и выполните эту вещь

Например

Родительская страница

<!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>
0 голосов
/ 17 января 2020

Во-первых: не используйте 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 не поддерживает его, например).

...