Кросс-домен postMessage, идентифицировать iFrame

Я использую postMessage для отправки событий из iframe в родительский документ. Я контролирую обе стороны, но контент поступает из двух разных областей.

enter image description here

моя простая проблема заключается в том, что я не могу определить iFrame внутри его родительского метода обратного вызова. Реализация выглядит следующим образом:

в iFrame:

parent.postMessage(JSON.stringify({action: "closeView" }),'*');

в Родительском окне:

window.addEventListener('message',function(event) {
if(event.origin !== 'https://example.com')
    return;

    // Parse message back to json
    var messageObject = JSON.parse(event.data);
    var source = event.source;
    /* this is returning: Window -URL- */
    console.log( source );
    /* This will throw Permission denied, although this code is inside of "parent" */
    console.log(source.parentNode);
},false);

Я хочу определите определенный родительский элемент iframe, который (логически) находится внутри родительского документа.

когда я пытаюсь использовать event.source.parentNode или некоторые jQuery на указанном объекте, Firefox говорит, Я не могу сделать это, чтобы предотвратить XSS, ошибка:Error: Permission denied to access property 'parentNode'

как я могу получить родительский элемент iFrame, который вызвал postMessage прослушивателя событий?

3 ответов


для этого можно использовать имена окон, так как они переходят из тега iframe в контекст iframe.

родитель док:

<iframe name=fr2 src="data:text/html,%3Chtml%3E%0A%20%3Cscript%3E%20parent.postMessage%28%7Bname%3A%20window.name%7D%2C%20%22*%22%29%3B%3C/script%3E%0A%3C/html%3E"></iframe>
<iframe name=fr3 src="data:text/html,%3Chtml%3E%0A%20%3Cscript%3E%20parent.postMessage%28%7Bname%3A%20name%7D%2C%20%22*%22%29%3B%3C/script%3E%0A%3C/html%3E"></iframe>

<script>onmessage = function(e){ // use real event handlers in production
       alert("from frame: " + e.data.name);
 };</script>

iframe doc:

<html>
 <script> parent.postMessage({name: name}, "*");</script>
</html>

какие предупреждения "пластмассы fr2", затем "fr3 имеют". затем вы можете легко использовать имя attrib для поиска iframe в Родительском DOM с помощью селекторов attrib CSS.

иллюстративная демонстрация окна.имя + концепция iframe:http://pagedemos.com/namingframes/

это больно простой подход также невосприимчив к проблемам, возникающим из тех же URL-кадров.


Как я понимаю, это может быть попробовать здесь предположим, что url вашего главного окна www.abc.com\home.php

  <body>
         <iframe src="www.abc.com\getOtherDomainContent.php?otherUrl=www.xyz.com"/>
    </body>

getOtherDomainContent.php в этом файле нужно написать ajax-вызов, который получает содержимое перекрестного url-адреса и нажимает это содержимое в текущем окне iframe(getOtherDomainContent.php) часть тела.

getOtherDomainContent.РНР Код:

    <html>
         <head>
//import jqry lib or other you use.
          <script>
              $(document).ready({
               //getcontent of xyz.com
                var otherUrlContent=getAjaxHtml("www.xyz.com");
                 $("body").html(otherUrlContent);
                  // further  code after content pushed.
                  //you can easily access "parent.document" and else using parent which will give you all thing you want to do with your main window
                });
          </script>
         </head>
    </html>

Как видно в этой теме: источник postMessage IFrame можно сравнить каждый iframes contentWindow С event.source такой:

/*each(iframe...){ */
frames[i].contentWindow === event.source

подсказка: Когда дело доходит до использования перекрестного домена и iFrames, у вас нет доступа к id или name атрибут iFrame внутри iFrame, поэтому мы не можем получить их.

но мне это не слишком понравилось. Мое решение пока выглядит так:

в iFrame:

parent.postMessage(JSON.stringify({action: "closeView", viewUrl: document.URL}),'*');

обновление: docuent.URL может стать проблемой, когда вы используете запросы или ссылки с местоположением (#anchor), так как ваш текущий url-адрес будет отличаться от источника iframe. Так вместо document.URL лучше использовать [location.protocol, '//', location.host, location.pathname].join('') (есть ли способ получить url без строки запроса в Java script)

в Родительском документе:

window.addEventListener('message',function(event) {

    if(event.origin !== 'https://example.com')
        return;

    // Parse message back to json
    var messageObject = JSON.parse(event.data);
    // Get event triggering iFrame
    var triggerFrame = $('iframe[src="'+messageObject.viewUrl+'"]');

 },false);

каждое событие должно будет отправить текущий URL-адрес iframe родительского документа. Теперь мы можем сканировать наши документы для iFrame с заданным URL-адресом и работать с ним.

если некоторые из вас знают лучший способ, пожалуйста, опубликуйте свои ответы.