如何獲取跨域iframe高度

【技術(shù)研究】如何動態(tài)獲取跨域iframe高度

引言

iframe是一個“好東西”,但是又會帶給你很多頭疼的“問題”,特別是在ios的兼容性問題。在ios當中,iframe里的頁面不會隨著外層的網(wǎng)頁大小自適應彈性縮放。相比之下,PC瀏覽器瀏覽器和安卓的瀏覽器則是可以實現(xiàn)縮放,這導致了差異性。這時候第一時刻,想到的是兼容的寫法。專門針對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);
}

上述的兼容寫法能解決部分網(wǎng)站的問題,但是如果是響應式網(wǎng)頁,頁面跳動的情況還是會出現(xiàn)問題的。

隨著技術(shù)的發(fā)展,iframe一般都是萎了滿足跨域的頁面。受限于瀏覽器的同源政策,父頁面是沒法跨域獲取子網(wǎng)頁的高度或者寬度。這時候,我們可能考慮將iframe的高和寬“定死”。跨域交換iframe內(nèi)外的數(shù)據(jù)的方法有以下兩種,一種是中間代理頁面,一種是h5的API--postMessage。

中間代理頁面

參考iframe高度自適應的6個方法的最后一種方法,這種方法是建立了在兩個頁面中一個中間代理層。原理很簡單,用代理層網(wǎng)頁地址的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把高度和寬度值組織好到代理頁面的鏈接。由于鏈接的調(diào)用不受跨域的限制,也算是走了個“后門”,把你想要的值“偷偷”傳到代理頁面上。而代理頁面和主頁面同源,不構(gòu)成跨域,所以避免了瀏覽器的跨域限制。我們還需要在iframe目標頁面添加一段代碼,就是把添加一個iframe把數(shù)據(jù)往鏈接上拼接。在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的發(fā)展,postMessage是不同的html頁面之間進行數(shù)據(jù)通信的方法,大大簡化了上述方法的步驟。

在b.html中添加一段代碼,在它加載完成后,往父頁面跨域發(fā)送自己的高和寬,并且可以限制你發(fā)送的父網(wǎng)站的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網(wǎng)站添加一個事件監(jiān)聽,獲取iframe內(nèi)的b.html發(fā)送的高與寬,從而設置父頁面的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

總結(jié)

相比之下,第二種方法會比較簡單和有效。但是由于跨域限制,你不得不要求對方添加一段代碼去“消除”跨域限制,也是出于安全性不得已的實現(xiàn)方法。

總的來說,iframe在移動端受非常多的限制,盡可能地慎用。

參考

跨域iframe高度自適應的多種方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • 1. 什么是跨域? 跨域一詞從字面意思看,就是跨域名嘛,但實際上跨域的范圍絕對不止那么狹隘。具體概念如下:只要協(xié)議...
    w_zhuan閱讀 532評論 0 0
  • 來吧,少年,今天還能看文章學習的,一多半都是單身貴族,看朋友圈還會被虐,不如學習,上街還會被虐,不如學習,痛并快樂...
    范小飯_閱讀 7,995評論 3 24
  • 1. 什么是跨域? 跨域一詞從字面意思看,就是跨域名嘛,但實際上跨域的范圍絕對不止那么狹隘。具體概念如下:只要協(xié)議...
    他在發(fā)呆閱讀 829評論 0 0
  • 音頻:白天就循環(huán)下之前的peppa,海尼曼,牛津樹 視頻:2aU7 玩:2aU7 分級:新開8本牛津樹+eric ...
    麥太_ebbe閱讀 179評論 0 0
  • 從來沒有甘心駐足的風 卻有無數(shù)想和風私奔的風箏 風箏割斷連接大地的細長臍帶 撲向心曠神怡的藍 為什么飛也飛不高,追...
    子夜玄白閱讀 252評論 3 4