深入理解iframe


一、什么是 iframe

iframe 用於在頁面內顯示頁面,使用 <iframe> 會創建包含另外一個文檔的內聯框架(即行內框架)

<iframe src="URL"></iframe>

 

 

二、iframe 的常用屬性

 

1、width

定義 iframe 的寬度

 

2、height

定義 iframe 的高度

 

3、name

規定 iframe 的名稱

 

4、frameborder

規定是否顯示邊框,值為 0(不顯示)和 1(顯示)

 

5、scrolling

規定是否在 iframe 中顯示滾動條,值為 yes、no、auto

 

6、src

設置 iframe 的地址(頁面/圖片)

 

7、srcdoc

用來替換 iframe 中 html、body 里的內容( IE 不支持)

 

8、sandbox

對 iframe 進行內容限制,值為

  • allow-forms
  • allow-same-origin
  • allow-scripts
  • allow-top-navigation
  • ...

支持 IE10+

 

 

三、獲取 iframe 中的內容

 

1、獲取 iframe

var iframe = document.getElementById("iframe1");

 

2、iframe.contentWindow

獲取iframe的window對象

var iwindow = iframe.contentWindow;


3、iframe.contentDocument

獲取iframe的document對象

var idoc = iwindow.document;

 

4、window.frames['name']

這種方法同樣可以獲取 window 對象

var iwindow = window.frames['name'];

 

 

四、在 iframe 中獲取父級內容

 

1、window.parent

獲取上一級 window 對象( iframe 可以有多層使用)

 

2、window.top

獲取最頂級容器的 window 對象,即打開頁面時的文檔

 

3、window.self

返回自身 window 對象

 

 

五、iframe 的長輪詢 

 

長輪詢就是在 ajax 的 readyState = 4的時,再次執行原函數。

這里使用 iframe 也是一樣,異步創建 iframe,然后 reload

var iframeCon = docuemnt.querySelector('#container'),
        text; //傳遞的信息
    var iframe = document.createElement('iframe'),
        iframe.id = "frame",
        iframe.style = "display:none;",
        iframe.name="polling",
        iframe.src="target.html";
    iframeCon.appendChild(iframe);
    iframe.onload= function(){
        var iloc = iframe.contentWindow.location,
            idoc  = iframe.contentDocument;
        setTimeout(function(){
            text = idoc.getElementsByTagName('body')[0].textContent;
            console.log(text);
            iloc.reload(); //刷新頁面,再次獲取信息,並且會觸發onload函數
        },2000);
    }

這樣就可以實現 ajax 長輪詢的效果。 當然,這里只是使用 reload 進行獲取,也可以添加 iframe 和刪除 iframe 的方式,進行發送信息,這些都是根據具體場景應用的。

另外在 iframe 中還可以實現異步加載 js 文件,不過,iframe 和主頁是共享連接池的,現在基本上都被 XHR 和 hard calllback 取締了

 

 

六、自適應 iframe - 廣告嵌入

廣告通常與原文無關,如果直接在某個 div 下嵌套,會造成網頁布局的紊亂,而且還需要引入額外的 css 和 js 文件,極大降低了網頁的安全性。 這些所有的弊端,都可以使用iframe進行解決。 
可以將 iframe 理解為一個沙盒,里面的內容能夠被 top window 完全控制,而且,主頁的 css 樣式不會入侵 iframe 里面的樣式

默認情況下,iframe 會自帶滾動條,不會全屏,如果你想自適應iframe的話:


1、去掉滾動條

<iframe src="./iframe1.html" id="iframe1" scrolling="no"></iframe>

 

2、設置 iframe 的高為 body 的高

var iwindow = iframe.contentWindow;
var idoc = iwindow.document;
iframe.height = idoc.body.offsetHeight;

另外,還可以添加其它的裝飾屬性:

屬性 效果
allowtransparency true or false
是否允許iframe設置為透明,默認為false
allowfullscreen true or false
是否允許iframe全屏,默認為false

 

 

 

 

 

 

七、iframe 的安全性

 

1、防嵌套網頁

iframe 享有 click 優先權,當有人在偽造的主頁中進行點擊的話,如果點在 iframe 上,則會默認是在操作 iframe 的頁面。 所以,釣魚網站就是使用這個技術,通過誘導用戶進行點擊。
為了防止網站被釣魚,可以使用 window.top 來防止你的網頁被 iframe,即限定你的網頁不能被嵌套在任何網頁內:

//iframe2.html
if(window != window.top){
    window.top.location.href = correctURL;
}

 

2、X-Frame-Options

X-Frame-Options 是一個相應頭,主要是描述服務器的網頁資源的 iframe 權限,有3個選項:

  1. DENY:當前頁面不能被嵌套 iframe 里,即便是在相同域名的頁面中嵌套也不允許,也不允許網頁中有嵌套 iframe
  2. SAMEORIGIN:iframe 頁面的地址只能為同源域名下的頁面
  3. ALLOW-FROM:可以在指定的 origin url 的 iframe 中加載

簡單實例:

X-Frame-Options: DENY
拒絕任何iframe的嵌套請求

X-Frame-Options: SAMEORIGIN
只允許同源請求,例如網頁為 foo.com/123.php,則 foo.com 底下的所有網頁可以嵌入此網頁,但是 foo.com 以外的網頁不能嵌入

X-Frame-Options: ALLOW-FROM http://s3131212.com
只允許指定網頁的iframe請求,不過兼容性較差Chrome不支持

X-Frame-Options 其實就是將前端 js 對 iframe 的把控交給服務器來進行處理

//js
if(window != window.top){
    window.top.location.href = window.location.href;
}
//等價於
X-Frame-Options: DENY

//js
if (top.location.hostname != window.location.hostname) { 
    top.location.href =window.location.href;
}
//等價於
X-Frame-Options: SAMEORIGIN

該屬性是對頁面的 iframe 進行一個主要限制,不過,涉及 iframe 的 header 可不止這一個,另外還有一個 Content Security Policy,同樣也可以對 iframe 進行限制

 

3、sandbox

sandbox 就是用來給指定 iframe 設置一個沙盒模型限制 iframe 的更多權限
sandbox 是 h5 的一個新屬性,IE10+支持
啟用方式就是使用 sandbox 屬性:

<iframe sandbox src=”...”></iframe>

這樣會對iframe頁面進行一系列的限制:

  1. script 腳本不能執行
  2. 不能發送 ajax 請求
  3. 不能使用本地存儲,即 localStorage,cookie 等
  4. 不能創建新的彈窗和 window
  5. 不能發送表單
  6. 不能加載額外插件比如 flash 等

同時可以放寬一點權限。在 sandbox 里面進行一些簡單設置

<iframe sandbox=”allow-same-origin” src=”...”></iframe>

常用的配置項有:

配置 效果
allow-forms 允許進行提交表單
allow-scripts 運行執行腳本
allow-same-origin 允許同域請求,比如 ajax,storage
allow-top-navigation 允許 iframe 能夠主導 window.top 進行頁面跳轉
allow-popups 允許 iframe 中彈出新窗口,比如 window.open,target="_blank"
allow-pointer-lock 在 iframe 中可以鎖定鼠標,主要和鼠標鎖定有關

 

 

 

 

 

 

可以通過在 sandbox 里,添加允許進行的權限.

<iframe sandbox=”allow-forms allow-same-origin allow-scripts” src=”...”></iframe>

這樣可以保證 js 腳本的執行,但是禁止 iframe 里的 javascript 執行 top.location = self.location

 

 

八、iframe 的局限

 

1、創建比一般的 DOM 元素慢了 1-2 個數量級

iframe 的創建比其它包括 scripts 和 css 的 DOM 元素的創建慢了 1-2 個數量級,使用 iframe 的頁面一般不會包含太多 iframe,所以創建 DOM 節點所花費的時間不會占很大的比重。但帶來一些其它的問題:onload 事件以及連接池(connection pool)

 

2、阻塞頁面加載

及時觸發 window 的 onload 事件是非常重要的。onload 事件觸發使瀏覽器的 “忙” 指示器停止,告訴用戶當前網頁已經加載完畢。當 onload 事件加載延遲后,它給用戶的感覺就是這個網頁非常慢。

window 的 onload 事件需要在所有 iframe 加載完畢后(包含里面的元素)才會觸發。在 Safari 和 Chrome 里,通過 JavaScript 動態設置 iframe 的 SRC 可以避免這種阻塞情況

 

3、唯一的連接池

瀏覽器只能開少量的連接到 web 服務器。比較老的瀏覽器,包含 Internet Explorer 6 & 7 和 Firefox 2,只能對一個域名(hostname)同時打開兩個連接。這個數量的限制在新版本的瀏覽器中有所提高。Safari 3+ 和 Opera 9+ 可同時對一個域名打開 4 個連接,Chrome 1+, IE 8 以及 Firefox 3 可以同時打開 6 個

絕大部分瀏覽器,主頁面和其中的 iframe 是共享這些連接的。這意味着 iframe 在加載資源時可能用光了所有的可用連接,從而阻塞了主頁面資源的加載。如果 iframe 中的內容比主頁面的內容更重要,這當然是很好的。但通常情況下,iframe 里的內容是沒有主頁面的內容重要的。這時 iframe 中用光了可用的連接就是不值得的了。一種解決辦法是,在主頁面上重要的元素加載完畢后,再動態設置 iframe 的 SRC。

 

4、不利於 SEO

搜索引擎的檢索程序無法解讀 iframe。另外,iframe 本身不是動態語言,樣式和腳本都需要額外導入。綜上,iframe 應謹慎使用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM