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
编辑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+中工作.