如何獲取跨域iframe高度
【技術研究】如何動態獲取跨域iframe高度
引言
iframe是一個“好東西”,但是又會帶給你很多頭疼的“問題”,特別是在ios的相容性問題。在ios當中,iframe裡的頁面不會隨著外層的網頁大小自適應彈性縮放。相比之下,PC瀏覽器瀏覽器和安卓的瀏覽器則是可以實現縮放,這導致了差異性。這時候第一時刻,想到的是相容的寫法。專門針對ios專門設定iframe的scrolling屬性為“no”,其他瀏覽器為“yes”,如下方原始碼。但是如果iframe子頁面中存在�響應式部件tab,高度進行變化,則會引起重繪重排,導致頁面突然跳到頂部。
<div id="url-wrapper"></div>
html, body{
height: 100%;
}
#url-wrapper{
margin-top: 51px;
height: 100%;
}
#url-wrapper iframe{
height: 100%;
width: 100%;
}
#url-wrapper.ios{
overflow-y: auto;
-webkit-overflow-scrolling:touch !important;
height: 100%;
}
#url-wrapper.ios iframe{
height: 100%;
min-width: 100%;
width: 100px;
*width: 100%;
}
function create_iframe(url){
var wrapper = jQuery('#url-wrapper');
if(navigator.userAgent.match(/(iPod|iPhone|iPad)/)){
wrapper.addClass('ios');
var scrolling = 'no';
}else{
var scrolling = 'yes';
}
jQuery('<iframe>', {
src: url,
id: 'url',
frameborder: 0,
scrolling: scrolling
}).appendTo(wrapper);
}
上述的相容寫法能解決部分網站的問題,但是如果是響應�式網頁,頁面跳動的情況還是會出現問題的。
隨著技術的發展,iframe一般都是萎了滿足跨域的頁面。受限於瀏覽器的同源政策,父頁面是沒法跨域獲取子網頁的高度或者寬度。這時候,我們可能考慮將iframe的高和寬“定死”。跨域交換iframe內外的資料的方法有以下兩種,一種是中間代理頁面,一種是h5的API--postMessage。
中間代理頁面
參考iframe高度自適應的6個方法的最後一種方法,這種方法是建立了在兩個頁面中一箇中間代理層。原理很簡單,用代理層網頁地址的hash值傳高度和寬度。假設www.a.com域名下的一個頁面a.html要包含www.b.com下的一個頁面b.html。這時,我們需要在a域名下新增一個agent.html,代理層的程式碼如下,放置在自己的伺服器。
//agent.html
<script type="text/javascript">
var other = window.parent.parent.document.getElementById("other");
var hash_url = window.location.hash;
if (hash_url.indexOf("#") >= 0) {
var hash_width = hash_url.split("#")[1].split("|")[0] + "px";
var hash_height = hash_url.split("#")[1].split("|")[1] + "px";
other.style.width = hash_width;
other.style.height = hash_height;
}
</script>
而它是被iframe目標頁面所引用,iframe把高度和寬度值組織好到代理頁面的連結。由於連結的呼叫不受跨域的限制,也算是走了個“後門”,把你想要的值“偷偷”傳到代理頁面上。而代理頁面和主頁面同源,不構成跨域,所以避免了瀏覽器的跨域限制。我們還需要在iframe目標頁面新增一段程式碼,就是把新增一個iframe把資料往連結上拼接。在b.html的尾部加上這段js。
//b.html
(function autoHeight() {
var b_width = document.body.clientWidth;
var b_height = document.body.clientHeight;
var agent = document.getElementById("agent");
agent.src = agent.src + "#" + b_width + "|" + b_height; // 這裡通過hash傳遞b.htm的寬高
})();
而在a.html還是原封不動的那個iframe就可以了。
<!--a.html-->
<iframe src="./othersite.html" id="other" frameborder="0" scrolling="no" style="border:0px;"></iframe>
原始碼參考brandonxiang/iframe-height。
postMessage
有些人覺得上面的方法非常難理解,因為中間代理層的緣故,增加了請求量,影響了載入�效率。
隨著HTML5 API的發展,postMessage是不同的html頁面之間進行資料通訊的方法,大大簡化了上述方法的步驟。
在b.html中新增一段程式碼,在它載入完成後,往父頁面跨域傳送自己的高和寬,並且可以限制你傳送的父網站的ip地址,大大保證安全性。
//b.html
document.addEventListener('DOMContentLoaded', function () {
var tbody = document.body
var width = tbody.clientWidth
var height = tbody.clientHeight
window.parent.postMessage({ height: height, width: width }, '*')
}, false)
還需要在a.html網站新增一個事件監聽,獲取iframe內的b.html傳送的高與寬,從而設定父頁面的iframe的高與寬。
//a.html
var frame = document.getElementById('other')
window.addEventListener('message', function(e){
frame.style.height = e.data.height+'px'
frame.style.width = e.data.width+'px'
})
原始碼參考brandonxiang/iframe-height。
總結
相比之下,第二種方法會比較簡單和有效。但是由於跨域限制,你不得不要求對方新增一段程式碼去“消除”跨域限制,也是出於安全性不得已的實現方法。
總的來說,iframe在移動端受非常多的限制,儘可能地慎用。
相關文章
- iframe 跨域高度自適應跨域
- js獲取iframe和父級之間元素,方法、屬,獲取iframe的高度自適應iframe高度JS
- Vue嵌入iframe,iframe如何跨域呼叫vue內路由Vue跨域路由
- Iframe嵌入跨域頁面高度自適應實現詳解跨域
- 關於父視窗獲取跨域iframe子視窗中的元素跨域
- iframe 元素跨域訪問跨域
- jQuery如何獲取iframe中的元素jQuery
- IFrame跨域問題筆記跨域筆記
- IE中iframe跨域訪問跨域
- javascript如何獲取圖片的高度JavaScript
- iframe跨域的幾種常用方法跨域
- iframe跨域session丟失問題跨域Session
- JS獲取跨域的cookie例項JS跨域Cookie
- iframe高度處理
- iframe的操作-Js/Jquery獲取iframe中的元素JSjQuery
- js如何獲取元素的高度和寬度JS
- jQuery如何獲取元素的寬度和高度jQuery
- javascript 獲取iframe中內容JavaScript
- 跨域庫herryPostMessage.js的一些優化,多iframe跨域跨域JS優化
- JSONProxy – 獲取跨域json資料工具JSON跨域
- Android獲取view高度AndroidView
- JavaScript跨域(1):什麼是跨域,如何跨域JavaScript跨域
- html iframe高度自適應HTML
- jQuery獲取客戶區高度jQuery
- javascript獲取網頁的高度JavaScript網頁
- 實現跨域iframe介面方法呼叫 簡單介紹跨域
- 使用 postMessage 解決 iframe 跨域通訊問題跨域
- Android獲取狀態列高度Android
- keycloak~從login-status-iframe頁面總結如何跨域傳值~續跨域
- 獲取含跨域網址的框架網頁的原始碼跨域框架網頁原始碼
- js獲取操作iframe子頁面中元素JS
- iframe自適應高度的外掛
- iframe高度自適應解決方案
- jquery 實現iframe 自適應高度jQuery
- jquery獲取元素高度程式碼例項jQuery
- 完美獲取Android狀態列高度Android
- iOS 精準獲取webView內容高度並自適應高度iOSWebView
- 封裝一個postMessage庫,進行iframe跨域互動封裝跨域