一、什麼是 iframe iframe 用於在頁面內顯示頁面,使用 <iframe> 會創建包含另外一個文檔的內聯框架(即行內框架) 二、iframe 的常用屬性 1、width 定義 iframe 的寬度 2、height 定義 iframe 的高度 3、name 規定 iframe 的名稱 4、 ...
一、什麼是 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個選項:
- DENY:當前頁面不能被嵌套 iframe 里,即便是在相同功能變數名稱的頁面中嵌套也不允許,也不允許網頁中有嵌套 iframe
- SAMEORIGIN:iframe 頁面的地址只能為同源功能變數名稱下的頁面
- 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頁面進行一系列的限制:
- script 腳本不能執行
- 不能發送 ajax 請求
- 不能使用本地存儲,即 localStorage,cookie 等
- 不能創建新的彈窗和 window
- 不能發送表單
- 不能載入額外插件比如 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 應謹慎使用。