[英]cross-domain iframe resize
如何從另一個域調整 iframe 的大小?
過去幾天我一直在嘗試將 iframe 集成到網站中。 這是一個短期解決方案,而另一方開發和 API(可能需要幾個月......)因為這是我們想要使用 easyXDM 的短期解決方案 - 我可以訪問另一個域,但要求他們這樣做已經夠難了按原樣添加 p3p 標頭.....
3 個 iframe
我找到的最接近的解決方案是 3 個 iframe——但它是 chrome 和 safari 的精神,所以我不能使用它。
用鉻打開
http://css-tricks.com/examples/iFrameResize/crossdomain.php#frameId=frame-one&height=1179
測量滾動條
我發現了另一篇關於如何使用滾動高度來嘗試調整表單大小的帖子。理論上它運行良好,但我無法使用 iframe 滾動高度正確應用它。
document.body.scrollHeight
這顯然使用了身體高度(無法訪問這些屬性 100% 是基於客戶端顯示畫布而不是 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 登錄並且代理獲取登錄頁面而不是實際內容。 還有一些調用頁面兩次是不可接受的
http://www.codeproject.com/KB/aspnet/asproxy.aspx
http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/
重新渲染頁面
我沒有走這么遠,但是那里有 jscript 引擎可以查看源代碼並根據源文件重新呈現頁面。 但它需要破解那些 jscripts.. 這對於商業實體來說不是一個理想的情況......有些調用純 Java 小程序或服務器端渲染
http://en.wikipedia.org/wiki/Server-side_JavaScript
http://htmlunit.sourceforge.net/ <-java 不是 jscript
所有這些都可以通過 HTML5 套接字來完成。 但是easyXDM對於非HTML5投訴頁面來說是一個很好的后備方案。
解決方案 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.example/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>
在調用者域中,他們只需要在同一個地方添加intermediate_frame HTML 和easyXDM.js
。 就像父文件夾一樣 - 然后您可以訪問相關目錄或僅適合您的包含文件夾。
與 Sean 提到的類似,您可以使用 postMessage。 我花了很多時間嘗試不同的方法來調整跨域 iframe 的大小,但沒有運氣,直到我偶然發現了 David Walsh 的這篇很棒的博客文章:http: //davidwalsh.name/window-iframe
這是我的代碼和大衛的解決方案的組合。 我的解決方案專門針對調整 iframe 的大小。
在子頁面中,找到頁面的高度並將其傳遞給父頁面(包含 iframe)。 將 element_id 替換為您的元素 id(html、body 等)。
<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
在父窗口中,添加此代碼。 將 iframe_id 替換為您的 iframe ID:
<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>
如果您打開控制台,您將在控制台日志中看到正在打印的高度。 這將幫助您進行調試,這就是我將其留在那里的原因。
最好的,貝克
問題是 - 除了使用跨域消息傳遞之外別無他法,因為您需要從一個域中的文檔獲取計算高度到不同域中的文檔。
因此,您要么使用postMessage
(適用於所有現代瀏覽器)執行此操作,要么花 5 分鍾調整來自 easyXDM 的resize iframe 示例。
對方真的只需要復制幾個文件到他們的域中,然后在他們的文檔中添加一行代碼..
在看了很多不同的解決方案之后,我最終編寫了一個簡單的小型庫來考慮許多不同的用例。 因為我需要一個在門戶頁面上支持多個用戶生成的 iFrame 的解決方案,支持瀏覽器調整大小並且可以應對 iFrame 之后加載的主機頁面 JavaScript。 我還添加了對寬度大小和回調函數的支持,並允許覆蓋 body.margin,因為您可能希望將此設置為零。
https://github.com/davidjbradshaw/iframe-resizer
iframe 代碼只是一些自包含的 JavaScript,因此它是其他人頁面上的好客人。
然后使用以下可用選項在主機頁面上初始化腳本。
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
);
}
});
現在我只知道4個解決方案:
只有第三種才能解決很多問題。 例如,您可以創建響應式 iFrame ; 從里面關閉它,或者你可以與它交流。 但要做到這一點,您需要 iframe 中的 iFrame 和“第三方 cookie”解決方法(可選)。
我用示例創建了一篇關於它的文章:事件驅動的跨域 iFrame
您是否查看過“適合對象”的 HTML5 屬性? 將視頻/圖像縮放到 iframe,而不是縮放 iframe(如果您抓取最終寬度為 5,000 像素的中等大小的圖像,那就太好了)。 “適合”選項(其他是“覆蓋”和“填充”)使用一種信箱類型的方法來適應源,同時保留縱橫比。 對於那些沒有 HTML5 的人來說,看起來有很多可用的 polyfills。 這個很棒,但是 Edge 端的一個錯誤使它與微軟的 New Nightmare 不兼容大約一年,現在: https ://github.com/anselmh/object-fit
編輯:要解決跨域問題,您始終可以在 Chrome 擴展內容腳本中完成工作,因為它認為它是您粘貼 iframe 的頁面的一部分。
HTTPS 另一個鏈接獲取 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>
https://-b.com iframe 內容:
<!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>
工作表:
xcom http > ycom https 工作
xcom https > ycom https 工作
xcom http > ycom http 工作
xcom https > ycom http 工作
我沒有在 iframe 上使用 scroll=no,而是將其更改為“auto”。 然后,我得到實際窗口的大小
$(window).height();
並將其用作 iframe 高度屬性。
嗯,結果是……
我們永遠不會有“頁面”滾動,只有“iframe”滾動。 當你導航時,誰是卷軸並不重要,但重要的是只有 1 個。
好吧,存在用戶在導航時簡單地調整窗口大小的問題。 為了解決這個問題,我使用:
setInterval(getDocHeight, 1);
您是否認為該解決方案會導致任何錯誤? 它對我有用,在 iFrame 上我有 php 生成的動態內容。 我怕以后會出現這樣的錯誤...
要調整 iframe 的大小,這是一個簡單的腳本:
這在頭腦中:(這是為 php 腳本編寫的,對於 html,將 ' 更改為 " 並將 \" 更改為 '...
<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>"
頭尾
這在正文中(請記住,這是為 php 腳本編寫的,對於 html,將所有 ' 更改為 " 並將 \" 更改為 '...)
<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>
獎金:上面有一些提示。 因為它是為 php 腳本設置的,所以你可以用它做很多事情......要了解更多,做更多......
關鍵是“sizeframe1”....對於同一頁面上的多個“調整大小”,復制相同的腳本,但更改 iframe 中的 id 和頭部腳本中的名稱,還有 viola! 您在同一頁面上有多個大小調整器...效果很好!
有朋。
您是否要查找 iframe 中包含的頁面高度? 我有一些 javascript 工作,它檢查 iframe 內容的高度,然后將 iframe 的高度設置為內容的高度。
var Height = document.getElementById('iFrameId').contentWindow.document.body.scrollHeight;
document.getElementById('iFrameId').height = Height;
但是,這僅適用於您在 iframe 中顯示的頁面位於同一域中的情況。 如果不是,您將無法訪問所需的信息。 因此,訪問被拒絕錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.