Javascript 跨域iframe调整大小

Javascript 跨域iframe调整大小,javascript,html,css,iframe,cross-domain,Javascript,Html,Css,Iframe,Cross Domain,如何从另一个域调整iframe的大小 -编辑 向下滚动查看一些解决方案。。或者读一读如何不这样做:D 经过数小时的代码黑客攻击,结论是iframe中的任何内容都是不可访问的,即使是在我的域中呈现的滚动条。我尝试了很多技巧,但都没有用 为了节省时间,甚至不必走这条路,只需使用sendMessages进行跨域通信。 我使用了一些HTML0&&w!==如果宽度){ //高度已更改,请更新iframe。 iframe.width(如果宽度=w); } //仅用于调试-如果需要,可以删除下一行 $('bo

如何从另一个域调整iframe的大小

-编辑

向下滚动查看一些解决方案。。或者读一读如何不这样做:D

经过数小时的代码黑客攻击,结论是iframe中的任何内容都是不可访问的,即使是在我的域中呈现的滚动条。我尝试了很多技巧,但都没有用

为了节省时间,甚至不必走这条路,只需使用sendMessages进行跨域通信。 我使用了一些HTML<5的插件-请参阅下面的示例:)


过去几天我一直在尝试将iframe集成到站点中。这是一个短期解决方案,而另一方开发API(可能需要几个月…) 由于这是一个短期解决方案,我们确实希望使用easyXDM-我可以访问另一个域,但要求他们按原样添加p3p头是很困难的

3个iFrame

我找到的最接近的解决方案是3个iframes,但它与chrome和safari的功能类似,所以我不能使用它

镀铬

测量滚动条

我发现了另一篇关于如何使用scrollheight尝试调整表单大小的帖子。。理论上它工作得很好,但我无法使用iframes滚动高度正确应用它

document.body.scrollHeight
obvoisly使用主体高度(无法访问这些属性100%基于客户端显示canvaz,而不是x域文档高度)

我尝试使用jquery获取iFrame的高度

$('#frameId').Height()

$('#frameId').clientHeight

$('#frameId').scrollHeight
在chrome和ie中返回的值不同——或者根本没有意义。 问题是帧内的所有内容都被拒绝-甚至滚动条

计算样式

但是如果我检查iframe的chrome中的元素,它会显示iframe中的文档维度(使用jquery x-domain获取iframe.heigh-拒绝访问) 计算的CSS中没有任何内容

那么chrome是如何计算的呢?(编辑-浏览器使用其内置呈现引擎重新呈现页面,以计算所有这些设置-但不会附加到任何位置以防止跨域欺诈..因此..)

HTML4

我读过HTML4.x规范,它说应该通过document.element公开只读值,但通过jquery拒绝访问

代理帧

我走了一条路线,将站点代理回去,然后计算哪一个是可以的。。直到用户通过iframe登录并且代理获得登录页面而不是实际内容。对某些人来说,两次调用页面也是不可接受的

重新呈现页面

我并没有走这么远,但是有jscript引擎可以查看源代码并基于源文件重新呈现页面。但这需要破解那些JScript。。对于商业实体来说,这不是一个理想的情况。。。 还有一些涉及纯java小程序或服务器端渲染

0&&h!==如有需要(高度){ //高度已更改,请更新iframe。 iframe.高度(如果高度=h); } 如果(!isNaN(w)&&w>0&&w!==如果宽度){ //高度已更改,请更新iframe。 iframe.width(如果宽度=w); } //仅用于调试-如果需要,可以删除下一行 $('body')。前置(“接收的”+h+“hX”+w+“w..); //可选的源URL(不支持window.postMessage时忽略)。 //在这里,您只能输入其他域名.com!这就像防止欺骗和xss攻击的身份验证! }, 'http://www.OTHERDOMAIN.co.uk'); });
选择3 他们现在是一个用于管理跨域iFrame的小JS库,它仍然需要iFrame中包含一点JavaScript,然而,这只是本地JS的2.8k(765字节gzip),没有任何依赖性,并且在父页面调用之前不会做任何事情。这意味着它是其他人系统中的好客人

这段代码使用mutationObserver来检测DOM更改,并查看调整大小事件,以便iFrame的大小与内容保持一致。在IE8+中工作


是否要查找iframe中包含的页面高度?我使用了一些javascript检查iframe内容的高度,然后将iframe的高度设置为内容的高度

var Height = document.getElementById('iFrameId').contentWindow.document.body.scrollHeight;

document.getElementById('iFrameId').height = Height;

但是,只有当您在iframe中显示的页面位于同一域上时,这才有效。如果不是,则无法访问所需信息。因此,访问被拒绝的错误。

问题是-除了使用跨域消息传递,没有其他方法,因为您需要获得从一个域中的文档到另一个域中的文档的计算高度

因此,要么使用
postMessage
(适用于所有moder浏览器),要么花5分钟从easyXDM改编


另一方实际上只需要将一些文件复制到他们的域中,并在文档中添加一行代码。

我将其更改为“自动”,而不是在iframe上使用scroll=no。然后,我得到实际窗口的大小

$(window).height();
并将其用作iframe高度属性

结果是

我们永远不会有“页面”滚动,只有“iframe”滚动。当你导航时,谁是卷轴并不重要,但重要的是只有1个卷轴

问题是,用户在导航时只需调整窗口大小。为了解决这个问题,我使用:

setInterval(getDocHeight, 1);

您认为该解决方案会导致任何错误吗?它为我工作,在iFrame上,我使用php生成了动态上下文。我担心将来会出现错误…

与肖恩提到的类似,您可以使用postMessage。我花了很多时间尝试不同的方法来调整ifr的大小
    <!doctype html>
<html>
    <head>

        <title>Frame</title>
        <script type="text/javascript" src="easyXDM.js">
        </script>
        <script type="text/javascript">
            var iframe;
            var socket = new easyXDM.Socket({
                //This is a fallback- not needed in many cases
                swf: "easyxdm.swf",
                onReady: function(){
                    iframe = document.createElement("iframe");
                    iframe.frameBorder = 0;
                    document.body.appendChild(iframe);
                    iframe.src = "THE HOST FRAME";
            iframe.onchange = messageBack();

                },
                onMessage: function(url, origin){
                    iframe.src = url;
                }
            });

            //Probe child.frame for dimensions.
            function messageBack(){
                socket.postMessage ( iframe.contentDocument.body.clientHeight + "," + iframe.contentDocument.body.clientWidth); 
            };

            //Poll for changes on children every 500ms.
            setInterval("messageBack()",500); 

        </script>
        <style type="text/css">
            html, body {
                overflow: hidden;
                margin: 0px;
                padding: 0px;
                width: 100%;
                height: 100%;
            }

            iframe {
                width: 100%;
                height: 100%;
                border: 0px;
            }
        </style>
    </head>
    <body>

    </body>
</html>
Excellent Work to  Sean Kinsey  who made the script!!!
<script src="scripts/jquery-1.5.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery.postmessage.min.js" type="text/javascript"></script>
<script src="scripts/club.js" type="text/javascript"></script>
 $(document).ready(function () {   
    var parent_url = decodeURIComponent( document.location.hash.replace( /^#/, '' ) ),link;
//Add source url hash to each url to authorise callback when navigating inside the frame.Without this clicking any links will break the communication and no messages will be received
$('a[href]').each(function(){ 
     this.href = this.href + document.location.hash ;
});
//Get the dimensions and send back to calling page.
var h1 = document.body.scrollHeight;
var w1 = document.body.scrollWidth;
$.postMessage({ if_height: h1, if_width: w1 }, parent_url, parent );
  });
  //This is almost like request.querystring used to get the iframe data
  function querySt(param, e) {
         gy = e.split("&");
         for (i = 0; i < gy.length; i++) {
             ft = gy[i].split("=");
             if (ft[0] == param) {
                 return ft[1];
             }
         }
     }


     $(function () {
         // Keep track of the iframe dimensions.
         var if_height;
         var if_width;
         // Pass the parent page URL into the Iframe in a meaningful way (this URL could be
         // passed via query string or hard coded into the child page, it depends on your needs).
         src = 'http://www.OTHERDOAMIN.co.uk/OTHERSTARTPAGE.htm' + '#' + encodeURIComponent(document.location.href),
         // Append the Iframe into the DOM.
         iframe = $('<iframe " src="' + src + '" width="100%" height="100%" scrolling="no" frameborder="0"><\/iframe>').appendTo('#iframe');

         // Setup a callback to handle the dispatched MessageEvent event. In cases where
         // window.postMessage is supported, the passed event will have .data, .origin and
         // .source properties. Otherwise, this will only have the .data property.
         $.receiveMessage(function (e) {
             // Get the height from the passsed data.
             //var h = Number(e.data.replace(/.*if_height=(\d+)(?:&|$)/, '$1'));
             var h = querySt("if_height", e.data);
             var w = querySt("if_width", e.data);


             if (!isNaN(h) && h > 0 && h !== if_height) {
                 // Height has changed, update the iframe.
                 iframe.height(if_height = h);
             }
             if (!isNaN(w) && w > 0 && w !== if_width) {
                 // Height has changed, update the iframe.
                 iframe.width(if_width = w);
             }
             //For debugging only really- can remove the next line if you want
             $('body').prepend("Recieved" + h + "hX" + w + "w .. ");
             // An optional origin URL (Ignored where window.postMessage is unsupported).
           //Here you must put the other domain.com name only! This is like an authentication to prevent spoofing and xss attacks! 
         }, 'http://www.OTHERDOMAIN.co.uk');
     });
var Height = document.getElementById('iFrameId').contentWindow.document.body.scrollHeight;

document.getElementById('iFrameId').height = Height;
$(window).height();
setInterval(getDocHeight, 1);
<script>
function adjust_iframe_height(){
    var actual_height = document.getElementById('element_id).scrollHeight;
    parent.postMessage(actual_height,"*"); 
    //* allows this to post to any parent iframe regardless of domain
}
</script>

<body onload="adjust_iframe_height();"> 
//call the function above after the content of the child loads
<script>
// Create IE + others compatible event handler
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

// Listen to message from child window
eventer(messageEvent,function(e) {
  console.log('parent received message!:  ',e.data);
  document.getElementById('iframe_id').height = e.data + 'px';
},false);
</script>
iFrameResize({
    log                    : true,  // For development
    autoResize             : true,  // Trigering resize on events in iFrame
    contentWindowBodyMargin: 8,     // Set the default browser body margin style (in px)
    doHeight               : true,  // Calculates dynamic height
    doWidth                : false, // Calculates dynamic width
    enablePublicMethods    : true,  // Enable methods within iframe hosted page 
    interval               : 32,    // interval in ms to recalculate body height, 0 to disable refreshing
    scrolling              : false, // Enable the scrollbars in the iFrame
    callback               : function(messageData){ // Callback fn when message is received
        $('p#callback').html(
            '<b>Frame ID:</b> '    + messageData.iframe.id +
            ' <b>Height:</b> '     + messageData.height +
            ' <b>Width:</b> '      + messageData.width + 
            ' <b>Event type:</b> ' + messageData.type
        );
    }
});
<script type='text/javascript'>
<!--
function resizeIframe(id){
/*
this.obj=obj
//this.obj.width=null
//this.obj.width=window.frames[\"sizeframe1\"].document.body.scrollWidth
this.obj.style.height=\"\" // for Firefox and Opera
setTimeout(\"this.obj.style.height=this.obj.contentWindow.document.body.scrollHeight+(notIE?heightOffset:0)\",10) // setTimeout required for Opera
*/

el=document.getElementById(id)
el.style.height='200px' // for Firefox and Opera
setTimeout('el.style.height=el.contentWindow.document.body.scrollHeight+\"px\"',1) // setTimeout required for Opera
}

// -->
</script>"
<iframe onload='resizeIframe(this.id)' allowTransparency=\"true\" name='ccpaymentwindow' id='sizeframe1' marginwidth='1' marginheight='1' height='700' width='690' border='0' frameborder='1' scrolling='no' src='ccmslink.php?variable1=" . $variable1 . "'></iframe>
 <!DOCTYPE html>
    <html>
    <head>
        <title>Test Page</title>
    </head>
    <body>
        Test Page:
        <hr/>
        <iframe id="iframe" src="https://-b.com" style="width:100%;min-height:600px;border:none;" scrolling="no" ></iframe>
        <script>
        // browser compatibility: get method for event 
        // addEventListener(FF, Webkit, Opera, IE9+) and attachEvent(IE5-8)
        var myEventMethod = 
            window.addEventListener ? "addEventListener" : "attachEvent";
        // create event listener
        var myEventListener = window[myEventMethod];
        // browser compatibility: attach event uses onmessage
        var myEventMessage = 
            myEventMethod == "attachEvent" ? "onmessage" : "message";
        // register callback function on incoming message
        myEventListener(myEventMessage, function (e) {
            // we will get a string (better browser support) and validate
            // if it is an int - set the height of the iframe #my-iframe-id
            if (e.data === parseInt(e.data)) 
                document.getElementById('iframe').height = e.data + "px";
        }, false);
        </script>
    </body>
    </html>
<!DOCTYPE html>
<html>
<head>
    <title>Test Iframe Content</title>
    <script type="text/javascript">
    // all content including images has been loaded
    window.onload = function() {
        // post our message to the parent
        window.parent.postMessage(
            // get height of the content
            document.body.scrollHeight
            // set target domain
            ,"*"
        )
    };
</script>
</head>
<body>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>1
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>2
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>3
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>4
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>5
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>6
</body>
</html>