跨域iframe问题

62

比如,我有一个名为example.com的网站,其中嵌入了来自iframe.net域的iframe。现在我想阅读iframe的内容并传递一些参数以显示文本消息。例如,包含用户名的Hi。

现在的问题是两者之间无法建立连接,甚至我无法获取所使用的iframe的innerHTML,我尝试了以下方法:

document.getElementById('myframe').contentWindow.document.body.innerHTML;

它抛出错误“Permission denied to access property”。

有人知道如何在跨域平台上进行读写吗?


你可以使用easyxdm库在跨域之间进行通信。这是一个链接,请查看。我曾经使用过这种技术来调整跨域的iframe(宽度,高度)。我不确定这个库是否适用于你的情况。试一试吧。http://easyxdm.net/wp/ - Muhammad Sannan Khalid
1
嗨,穆罕默德,你介意分享一下你是如何实现这个的吗?如果你还记得的话 - 感激的是这已经快7年了。 - Sparlarva
可以做到,但有一些限制。您可以查看此链接:https://alfilatov.com/posts/how-to-pass-data-between-iframe-and-parent-window/ - Alex Filatov
5个回答

81

如果您无法控制框架站点,则无法规避跨域策略。

如果您可以控制两个站点,则可以使用postMessage方法在不同的域之间传输数据。一个非常基本的示例:

// framed.htm:
window.onmessage = function(event) {
    event.source.postMessage(document.body.innerHTML, event.origin);
};

// Main page:
window.onmessage = function(event) {
    alert(event.data);
};

// Trigger:
// <iframe id="myframe" src="framed.htm"></iframe>
document.getElementById('myframe').contentWindow.postMessage('','*');

2
有没有任何反向跨域代理的黑客技巧可以实现这一点? - Kunal Vashist
1
@KunalVashist 这取决于你的应用程序(需要更多细节)。另外,看一下这个问题:绕过同源策略的方法 - Rob W
谢谢@rob,这个不错,但最终我无法访问框架内容。 - Kunal Vashist
如果您正在使用jQuery:$(window).on('message', evt=>evt.originalEvent.data //... - chiliNUT
2
https://dev59.com/T3I95IYBdhLWcg3wxA8-#41566923 <-- 这个回答类似,但是有更多的细节。 - Joe Coyle
显示剩余2条评论

7

在Internet Explorer 8中,作为参数传递的事件可能是null,因此您需要以不同的方式访问事件:

在frame.html中:

window.onmessage = function(event) {
   var evt = event || window.event;
   evt.source.postMessage('Message from iFrame', evt.origin);
};

main.html文件中:

window.onmessage = function(event) {
   var evt = event || window.event;
   alert(evt.data);
};

事件的触发方式与Rob W所展示的方式相同:
document.getElementById('frameId').contentWindow.postMessage('message','*');

0

只有当您对两个站点都有控制权时才会发生这种情况

您可以使用postMessage

以下是如何应用它的方法

首先,您可以将以下代码添加到要从中检索数据的站点

 <script>
        function test() {       
 document.getElementById('idMyIframe').contentWindow.postMessage("your message here", "*");
        }
    </script>
    <iframe id="idMyIframe" onload="test()" src="http://example.otherdomaintosenddatato.com"></iframe>

第二步,您可以将以下代码添加到要发送消息或数据的其他域中

 window.addEventListener("message", function (message) {
        if (message.origin == "http://firstdomain.com") {
            console.log(message)
        }
    });

请注意,在iframe的onload属性中添加test()函数,因为如果函数在iframe加载之前运行,它将变得无用,并且不会发送数据。

-1

使用(srcDoc)在React中跨域访问iframe元素:

<iframe srcDoc={this.state.HTML}  width='100%' id='iframetnd' onLoad={this.onclickinsideiframe}/>


 onclickinsideiframe=()=>{
      if(document.getElementById('iframetnd')!==null){

                let iframe = document.getElementById('iframetnd');

                let innerDocument = (iframe.contentDocument)  
                                   ? iframe.contentDocument 
                                   : iframe.contentWindow.document;
                let Obj = innerDocument.getElementsByClassName("navButtons")[0];
                    if(Obj !== undefined){
                        Obj.onclick = ()=>this.func();
          }
       }
    }



  func=()=>{
           this.setState({page:2})
           this.arrangeTest();
        }

-2

iFrame 不允许从跨域平台访问内容。只有当您的 iFrame 使用相同的域时,才能访问。

这个解决方案与 iFrame 相同。我创建了一个 PHP 脚本,可以获取其他网站的所有内容,最重要的是您可以轻松地将自定义 jQuery 应用于外部内容。请参考以下脚本,它可以获取其他网站的所有内容,然后您也可以应用您的自定义 jQuery/JS。此内容可在任何元素或页面内使用。

<div id='myframe'>

  <?php 
   /* 
    Use below function to display final HTML inside this div
   */

   //Display Frame
   echo displayFrame(); 
  ?>

</div>

<?php

/* 
  Function to display frame from another domain 
*/

function displayFrame()
{
  $webUrl = 'http://[external-web-domain.com]/';

  //Get HTML from the URL
  $content = file_get_contents($webUrl);

  //Add custom JS to returned HTML content
  $customJS = "
  <script>

      /* Here I am writing a sample jQuery to hide the navigation menu
         You can write your own jQuery for this content
      */
    //Hide Navigation bar
    jQuery(\".navbar.navbar-default\").hide();

  </script>";

  //Append Custom JS with HTML
  $html = $content . $customJS;

  //Return customized HTML
  return $html;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接