javascript 跨域postMessage,识别iFrame

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23629421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 01:14:42  来源:igfitidea点击:

Cross domain postMessage, identify iFrame

javascripthtmlcross-domainxss

提问by Nico O

I use postMessageto send events from an iframe to it's parent document. I have control over both sides but the content comes from two different domains.

postMessage用来将事件从 iframe 发送到它的父文档。我可以控制双方,但内容来自两个不同的域。

enter image description here

enter image description here

My simple problem is, that i can not identify the iFrame inside of it's parent callback method. The implementation looks like this:

我的简单问题是,我无法识别其父回调方法中的 iFrame。实现如下所示:

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.parentNodeor 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 或一些 jQuery 时,Firefox 说,我不能这样做来防止 XSS,错误:Error: Permission denied to access property 'parentNode'

How can i get the parent element of the iFrame, that triggered the postMessageevent listener?

如何获取触发postMessage事件侦听器的 iFrame 的父元素?

回答by dandavis

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 文档:

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

which alerts "fr2", then "fr3". you can then easily use the nameattrib to find the iframe in the parent DOM using attrib CSS selectors.

哪个警报“fr2”,然后是“fr3”。然后,您可以轻松地使用名称attrib 使用 attrib CSS 选择器在父 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 引起的问题的影响。

回答by Pratik Patel

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 需要编写 ajax 调用,获取跨 url 内容并将该内容推送到当前 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>

回答by Nico O

Like seen in this thread: postMessage Source IFrameit is possible to compare each iframes contentWindowwith event.sourcelike this:

就像在这个线程看到:postMessage的来源的IFrame有可能每个I帧比较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 idor nameattribute of the iFrame inside the iFrame, so we can not obtain those.

提示:当涉及到跨域使用和 iFrame 时,您无法访问iFrame 内部 iFrame的idorname属性,因此我们无法获取这些。

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.URLcan 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. So Instead of document.URLit's better to use [location.protocol, '//', location.host, location.pathname].join('')(is there any method to get url without query string in java script)

更新:docuent.URL当您使用带有位置 (#anchor) 的查询或链接时,可能会成为一个问题,因为您当前的 url 将与 iframe 源之一不同。所以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. We now can scan our documents for the iFrame with the given URL and work with it.

每个事件都必须将当前 iFrame URL 发送到父文档。我们现在可以使用给定的 URL 扫描 iFrame 的文档并使用它。

If some of you know a better way please post your answers.

如果你们中的一些人知道更好的方法,请发布您的答案。