How do I resize an iframe from another domain

-编辑

向下滚动查找一些解决方案.或者阅读关于如何不这样做的文章:d

经过数小时的代码破解-结论是IFRAME中的任何东西都是不可访问的,即使是呈现在我的域上的滚动条也是如此.我try 了许多技巧,但都没有效果.

To save you time don't even go down this route just use sendMessages for cross domain communications.


过go 几天,我一直在try 将iframe集成到网站中.这是一个短期解决方案,而另一方开发和API(可能需要几个月…)

3 iframes

我找到的最接近的解决方案是3iframe--但是它会使 chromium 合金和狩猎变得疯狂,所以我不能使用它.

在 chromium 合金中打开

http://css-tricks.com/examples/iFrameResize/crossdomain.php#frameId=frame-one&height=1179

Measure the scrollbars

我发现了另一篇关于如何使用滚动高度来try 调整窗体大小的帖子.理论上它工作得很好,但是我不能使用iframes滚动高度正确地应用它.

document.body.scrollHeight

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

我try 使用jquery获取iframes的高度

$('#frameId').Height()

$('#frameId').clientHeight

$('#frameId').scrollHeight

返回值在Chrome和ie中不同-或者根本没有意义. 问题是框架内的所有东西都被拒绝了-即使是滚动条.

Computed Styles

但是如果我判断并在iframe的Chrome中添加元素,它会向我显示iframe中的文档尺寸(使用jQuery x-domain获取iframe.heigh-access被拒绝) 计算出的css中没有任何内容在此输入图像描述

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

HTML4

我阅读了HTML4的规范.它说应该有通过文档公开的只读值.元素,但通过jquery它的访问被拒绝

Proxy Frame

我走了一条路由,将站点代理回go ,然后计算哪一个是可以的..直到用户通过iframe登录,代理获得的是登录页面而不是实际内容.对一些人来说,打两次电话是不可接受的

http://www.codeproject.com/KB/aspnet/asproxy.aspx

http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/

Re-Render the page

我没有走到这一步,但是有一些jscript引擎可以查看源代码并根据源文件重新呈现页面.但这需要破解那些jscript..对于商业实体来说,这并不是一个理想的情况. 且有些涉及纯Java小程序或服务器端呈现

http://en.wikipedia.org/wiki/Server-side_JavaScript

http://htmlunit.sourceforge.net/<-java不是jscript

http://maxq.tigris.org/


编辑09-2013

所有这些都可以通过HTML5套接字实现.但对于非HTML5投诉页面,easyXDM是一个很好的退路.

Solution 1非常棒的解决方案!

使用easyXDM

在服务器上,您以

<html>
<head>
<script src="scripts/easyXDM.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">

    var transport = new easyXDM.Socket(/** The configuration */{
    remote: "http://www.OTHERDOMAIN.com/resize_intermediate.html?url=testpages/resized_iframe_1.html",

    //ID of the element to attach the inline frame to
    container: "embedded",
    onMessage: function (message, origin) {
        var settings = message.split(",");
        //Use jquery on a masterpage.
        //$('iframe').height(settings[0]);
        //$('iframe').width(settings[1]);

        //The normal solution without jquery if not using any complex pages (default)
        this.container.getElementsByTagName("iframe")[0].style.height = settings[0];
        this.container.getElementsByTagName("iframe")[0].style.width = settings[1];
    }
});

</script>

</head>

<body>
    <div id="embedded"></div>
</body>

在调用域上,他们只需要在同一位置添加intermiedate_frame html和easyXDM.js.就像父文件夹一样-然后您可以只为您访问相对目录或包含的文件夹.

选项1

If you don't want to add scripts to all pages look at option 2!

然后,他们只需在您需要调整大小的每个页面的末尾添加一个简单的jscript即可.不需要在每个页面中都包含easyxdm.

 <script type="text/javascript">
            window.onload = function(){ parent.socket.postMessage( (parseInt(document.body.clientHeight)) + "," + ( document.body.clientWidth ) );  };
        </script>

我已经修改了它发送的参数.如果您希望宽度正常工作,则其他域上的页面需要在某种样式中包含页面的宽度,该样式看起来类似于:

<style type="text/css">
            html, body {
                overflow: hidden;
                margin: 0px;
                padding: 0px;
                background-color: rgb(75,0,85);
                color:white;
                width:660px
            }
            a {
            color:white;
            visited:white;
            }
        </style>

这对我很有用.如果不包括宽度,那么框架的行为有点奇怪,并试图猜测它应该是什么..如果你需要它,它不会缩小.

Select 2

Modify the intermediate frame to poll for changes

您的中间帧应该如下所示.

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

如果尺寸发生变化,间隔可以更有效地进行判断,并且只有尺寸发生变化时才发送,而不是每500毫秒发送一次消息.如果执行此判断,则可以将轮询更改为50毫秒!玩得高兴


跨浏览器工作,速度很快.伟大的调试功能!!

Excellent Work to  Sean Kinsey  who made the script!!!

Solution 2(有效,但不是很好)

因此,基本上,如果您与其他域达成了共同协议,那么您可以添加一个库来处理sendmessage.如果您没有访问其他域的任何权限..继续寻找更多的黑客-因为我找不到或完全证明我找到的这些是合理的.

因此另一个域会将这些包含在头标记号中

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

在club.js中只有一些我为Resize调用所做的自定义调用,并且包含..

 $(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');
     });

备选方案3

他们现在是一个用于管理跨域iFrame调整大小的小型JS库,它仍然需要iframe中包含一些JavaScript,然而,这只是2.8k(765字节Gzip)的原生JS,没有任何依赖关系,并且在被父页面调用之前不会做任何事情.这意味着它在其他人的系统上是一个很好的客人.

这段代码使用maturationWatch来检测DOM更改,并查找调整大小事件,以便使iframe保持与内容相适应的大小.在IE8+中工作.

https://github.com/davidjbradshaw/iframe-resizer

推荐答案

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

因此,要么使用postMessage(适用于所有现代浏览器),要么花费5分钟从easyXDM改编resize iframe example.

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

Css相关问答推荐

主dart 文件未加载Flutter Web

如何改变图标的 colored颜色 时悬停在

如何允许在bslb中 Select 输入重叠卡片?

Astro网站在使用Astro Build构建后无法正常工作

带高度的容器查询不工作,但可随宽度调整

为什么继承时1rem值不同?

使用 Flex 容器,如何在右对齐所有 Flex 子项的同时赋予子图像完整宽度?

更改行数时更改 CSS 网格列

before 元素的过渡效果

如何在相对位置和绝对位置之间转换元素?

Tailwind CSS 隐藏和可见

为什么我们将