简体   繁体   English

跨域postMessage,识别iFrame

[英]Cross domain postMessage, identify iFrame

I use postMessage to send events from an iframe to it's parent document. 我使用postMessage将事件从iframe发送到它的父文档。 I have control over both sides but the content comes from two different domains. 我控制了双方,但内容来自两个不同的领域。

在此输入图像描述

My simple problem is, that i can not identify the iFrame inside of it's parent callback method. 我的简单问题是,我无法识别其内部回调方法中的iFrame。 The implementation looks like this: 实现如下:

In the iFrame: 在iFrame中:

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

In the parent window: 在父窗口中:

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);

I want to identify a certain parent element of the iframe, which is (logically) inside of the parent document. 我想识别iframe的某个父元素,它在(逻辑上)在父文档中。

When i try to use event.source.parentNode or some jQuery on said object, Firefox says, i can not do this to prevent XSS, error: Error: Permission denied to access property 'parentNode' 当我尝试在所述对象上使用event.source.parentNode或一些jQuery时,Firefox说,我不能这样做以防止XSS,错误: Error: Permission denied to access property 'parentNode'

How can i get the parent element of the iFrame, that triggered the postMessage event listener? 如何获取触发postMessage事件侦听器的iFrame的父元素?

you can use window names for this, as they pass from iframe tag to iframe context. 您可以使用窗口名称,因为它们从iframe标记传递到iframe上下文。

parent doc: 父文件:

<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: iframe doc:

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

which alerts "fr2", then "fr3". 提醒“fr2”,然后“fr3”。 you can then easily use the name attrib to find the iframe in the parent DOM using attrib CSS selectors. 然后,您可以使用attrib CSS选择器轻松使用名称 attrib在父DOM中查找iframe。

illustrative demo of window.name+iframe concept: http://pagedemos.com/namingframes/ window.name + iframe概念的说明性演示: http//pagedemos.com/namingframes/

this painfully simple approach is also immune to issues arising from same-url iframes. 这种痛苦的简单方法也不受同一网址iframe引起的问题的影响。

As per my understanding this may be try here suppose your main window's url is www.abc.com\\home.php 根据我的理解,这可能是尝试这里假设您的主窗口的URL是www.abc.com \\ home.php

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

getOtherDomainContent.php in this file need to write ajax call which get cross url content and push that content in current iframe window(getOtherDomainContent.php)'s body part. 此文件中的getOtherDomainContent.php需要编写一个获取交叉URL内容的ajax调用,并将该内容推送到当前iframe窗口(getOtherDomainContent.php)的正文部分。

getOtherDomainContent.php Code: getOtherDomainContent.php代码:

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

Like seen in this thread: postMessage Source IFrame it is possible to compare each iframes contentWindow with event.source like this: 就像在这个帖子中看到的那样: postMessage Source IFrame可以将每个iframes contentWindowevent.source进行比较,如下所示:

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

Hint: When it comes to cross domain usage and iFrames, you have no access to the id or name attribute of the iFrame inside the iFrame, so we can not obtain those. 提示:当涉及到跨域使用和iFrame时,您无法访问iFrame中iFrame的idname属性,因此我们无法获取这些属性。

But i did not like this too much. 但我不太喜欢这个。 My solution for now looks like this: 我现在的解决方案如下所示:

In the iFrame: 在iFrame中:

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

Update: docuent.URL can become a problem, when you use queries or links with location (#anchor) since your current url will become different from the one of the iframe source. 更新:当您使用查询或带位置的链接(#anchor)时, docuent.URL可能会成为问题,因为您当前的网址将与iframe网格中的网址不同。 So Instead of document.URL it's better to use [location.protocol, '//', location.host, location.pathname].join('') ( is there any method to get url without query string in java script ) 所以代替document.URL最好使用[location.protocol, '//', location.host, location.pathname].join('')是否有任何方法在java脚本中获取没有查询字符串的url

In the parent document: 在父文档中:

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);

Each event will have to send the current iFrame URL to the parent document. 每个事件都必须将当前的iFrame URL发送到父文档。 We now can scan our documents for the iFrame with the given URL and work with it. 我们现在可以使用给定的URL扫描iFrame的文档并使用它。

If some of you know a better way please post your answers. 如果你们中的一些人知道更好的方式,请发表你的答案。

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

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