Iframe 有什麼好處,有什麼壞處?國內還有哪些知名網站仍用Iframe,為什麼?有哪些原來用的現在拋棄了?又是為什麼?


iframe原本的用法在現在看來是不合時宜的,問題太多了,不一一列舉,但是它的其他功能卻是不錯的黑魔法,這裡列舉一些,想到了再更新:

  1. 用來實現長連接,在websocket不可用的時候作為一種替代,最開始由google發明。Comet:基於 HTTP 長連接的「伺服器推」技術
  2. 跨域通信。JavaScript跨域總結與解決辦法 ,類似的還有瀏覽器多頁面通信,比如音樂播放器,用戶如果打開了多個tab頁,應該只有一個在播放。
  3. 歷史記錄管理,解決ajax化網站響應瀏覽器前進後退按鈕的方案,在html5的history api不可用時作為一種替代。
  4. 純前端的utf8和gbk編碼互轉。比如在utf8頁面需要生成一個gbk的encodeURIComponent字元串,可以通過頁面載入一個gbk的iframe,然後主頁面與子頁面通信的方式實現轉換,這樣就不用在頁面上插入一個非常巨大的編碼映射表文件了,其中子頁面內容:

    &
    &
    &
    &
    &
    window.encoding = function(str){
    //利用a元素的href屬性來encode
    var a = document.createElement("a");
    a.href = "/?q=" + str;
    var url = a.href; //這裡讀取的時候會自動編碼
    a.href = "/?q=";
    return url.replace(a.href, "");
    };
    &

    &

    &

    把這個iframe部署到父頁面的同源服務上,就能在父頁面直接調用iframe中的encoding介面了。

  5. 評論里有提到,用iframe實現無刷新文件上傳,在FormData不可用時作為替代方案
  6. 在移動端用於從網頁調起客戶端應用(此方法在iphone上並不安全,慎用!具體風險看這裡 iOS URL Scheme 劫持 )。比如想在網頁中調起支付寶,我們可以創建一個iframe,src為:

    alipayqr://platformapi/startapp?saId=10000007clientVersion=3.7.0.0718qrcode={支付二維碼掃描的url}

    瀏覽器接收到這個url請求發現未知協議,會交給系統處理,系統就能調起支付寶客戶端了。我們還能趁機檢查一下用戶是否安裝客戶端:給iframe設置一個3-5秒的css3的transition過渡動畫,然後監聽動畫完成事件,如果用戶安裝了客戶端,那麼系統會調起,並將瀏覽器轉入後台運行,進入後台的瀏覽器一般不會再執行css動畫,這樣,我們就能通過判斷css動畫執行的時長是否超過預設來判斷用戶是否安裝某個客戶端了:

    /**
    * 調起客戶端
    * @param url {String}
    * @param onSuccess {Function}
    * @param onFail {Function}
    */
    module.exports = function(url, onSuccess, onFail){
    // 記錄起始時間
    var last = Date.now();

    // 創建一個iframe
    var ifr = document.createElement("IFRAME");
    ifr.src = url;
    // 飄出屏幕外
    ifr.style.position = "absolute";
    ifr.style.left = "-1000px";
    ifr.style.top = "-1000px";
    ifr.style.width = "1px";
    ifr.style.height = "1px";
    // 設置一個4秒的動畫用於檢查客戶端是否被調起
    ifr.style.webkitTransition = "all 4s";
    document.body.appendChild(ifr);
    setTimeout(function(){
    // 監聽動畫完成時間
    ifr.addEventListener("webkitTransitionEnd", function(){
    document.body.removeChild(ifr);
    if(Date.now() - last &< 6000){ // 如果動畫執行時間在預設範圍內,就認為沒有調起客戶端 if(typeof onFail === "function"){ onFail(); } } else if(typeof onSuccess === "function") { // 動畫執行超過預設範圍,認為調起成功 onSuccess(); } }, false); // 啟動動畫 ifr.style.left = "-10px"; }, 0); };

  7. 創建一個全新的獨立的宿主環境。經 @EtherDream 大神提醒,iframe還可以用於創建新的宿主環境,用於隔離或者訪問原始介面及對象,比如有些前端安全的防範會覆蓋一些原生的方法防止惡意調用,那我們就能通過創建一個iframe,然後從iframe中取回原始對象和方法來破解這種防範。類似的還有 @賀師俊 曾經提到的javascript裸對象創建中的一種方法:如何創建一個JavaScript裸對象 ,一般所見即所得編輯器也是由iframe創建的, @Dion 的回答有提到
  8. IE6下用於遮罩select。經 @yaniv 提醒想起來的。曾經在ie6時代,想搞一個模態窗口,如果窗口疊加在select元素上面,是遮不住select的,為了解決這個問題,可以通過在模態窗口元素下面墊一個iframe來實現遮罩,好坑爹的ie6,還我青春韶華~~

  9. to be continued ...


  • 使用 iframe 是不是一個好的用法(good practice),不能一概而論,但是可以肯定是,現在的大部分網站避免採用這種方式的。
  • 比較早期的網站使用 iframe,主要是用於導航欄(navigator)。為什麼?

    因為一個網站很多頁面的導航欄部分是相同的,在避免切換頁面的時候重複下載,將導航欄和正文分開在 iframe 中,是一個方便的做法。

    同時帶來的不利是,默認情況下,使用了 iframe 的網站的 URL 不會隨著頁面的變化而變化。

    這就意味著一旦刷新,網站可能又回到首頁。

    那麼現在的網站是如何解決不同頁面使用相同的 navigator 而避免重複編碼呢?

    不同後台技術都有自己的方法,比如 ASP 有 SSI,PHP 有 require、require_once 或 include 函數,JSP 也有 include 指令。
  • iframe 一直是瀏覽器標準規範之一,只有很早期的瀏覽器不支持 iframe,現在幾乎已絕跡。

    所以從兼容性上來說,iframe 是沒問題的。
  • 那麼現在什麼時候會用到 iframe 呢?

    因為 iframe 的頁面和父頁面(parent)是分開的,所以它意味著,這是一個獨立的區域,不受 parent 的 CSS 或者全局的 JavaScript 的影響。

    典型的,比如所見即所得的網頁編輯器(WYSIWYG Online HTML Editor),因為它們需要 reset 自己的 CSS 到自己的標準,而不被 parent CSS 的 override。

  • 說到上面一點了,順便說一下,知乎的這個編輯器不是用 iframe,它使用了一種叫 contentEditable 的屬性,用來啟用頁面元素的編輯,在早期版本 IE 下不支持的。
  • 正是因為剛剛提到的 iframe 等於新建了一個全新的,不受 parent 影響的頁面上下文,所以在一定程度上,類似於沙箱隔離(sandbox)。

    除此之外,如果有可以不用 iframe 來解決的問題,還是避免使用 iframe。

    替代方案一般就是動態語言的 include 機制、ajax 動態填充內容,以及以後會普及的 contentEditable。


HTML規範說:The iframe element represents a nested browsing
context.

所以如果你需要獨立的瀏覽上下文,那麼就用 iframe,否則就不用。

歷史上,iframe 常被用於復用部分界面,但是多數情況下並不合適。

現在,應該使用 iframe 的例子如:

1. 沙箱隔離。

2. 引用第三方內容。

3. 獨立的帶有交互的內容,比如幻燈片。

4. 需要保持獨立焦點和歷史管理的子窗口,如複雜的Web應用。

註:登錄彈窗用 iframe 未必合適。HTML標準新增了dialog元素,可能更適合。


我也說一個吧,在手機web裡面,如果要載入大量圖片(例如一些瀑布了形式的圖片網站,或社交網站),一旦圖片載入過多,內存佔用大,頁面會stuck,如果使用iframe來載入一批圖片,當這批圖片滿足某個條件(例如遠離屏幕的可視區域),直接把iframe幹掉,清除內存佔用,乾淨利落~~


我再補充一個使用&

的網站吧,w3school的代碼測試頁面也使用了&

如圖


完全隔離的css 和 js , 但又可以使用 contentWindow和parent 來通信. 松耦合又不失靈活


剛剛看了下,QQ郵箱依然是iframe架構的。


一般郵箱這個東西用iframe的比較多


iframe現在不推薦大量使用,但是某些時候還是必要,比如模擬窗口,或者HTML在線編輯器等前面提到的。

iframe的優點就是隔離上下文網頁,

缺點也很明顯大量使用,打開一個網頁載入過多iframe體驗很不友好而且影響網頁載入速度。


分場景啊,現在很多網站的登陸彈窗都是用iframe,iframe有其語義,並不是一個要被廢棄的標籤。


現在用的很少了,最近也就是在寫Ajax文件上傳的時候用到過。


iframe用於隔離父-子頁面和提供特殊的布局格式,想上中下格式的沒必要用iframe

目前最多的是XX系統管理類似的網站,左邊一個菜單list,右邊就是iframe的tabs,可以隨時打開關閉頁面,對於系統管理真的很方便,這種系統,如果把iframe替換成DIV,那麼大量頁面中的相同類型的表格,表單等就要用不同的ID,CLASS,因為你的JS是針對BODY下的所有對象的,所以這種系統用IFRAME比較好,可以再IFRAME裡面自由使用JS和標籤的ID定義,而且父頁面和菜單列表一般不會刷新,所以IFRAME帶來的內容也就和一般頁面的刷新一樣。

還有關於IFRAME緩存的問題,這個問題太嚴重了,調試的時候經常會出現編輯器保存了,但是IFRAME裡面的表單內容沒有變,解決辦法就是IFRAME的SRC屬性的URL地址後面加一個隨機數,每次刷新IFRAME就都是不同的URL,那麼IFRAME就會去刷新了。


幾乎所有網站都在用啊。


網易雲音樂底部的播放條就是iframe實現的,誰說不好?


插入第三方網站內容?

比如想插入一個第三方的視頻,音頻,第三方網站可能對功能上有一些要求(廣告啥的),直接用video做不到,插入js怕第三方網站掛了,或js掛馬不安全,swf的話手機不支持,iframe就算是最好的方案了好了,所有的設備都可以訪問,並且父子頁面隔離。


好處就是便於更改,模塊分離,不好的地方就是spider不喜歡,因此seo優化經常用div代替frame


作弊的時候可以用iframe


1. 方便插入第三方內容,不擔心影響整體頁面載入,例如聯盟廣告

2. 緩存網頁,主要是在網路不好的時候

3. postMessage通信

4. 安全沙箱,避免污染環境

5. 流量作弊,嵌入一個不展現的iframe頁面,反作弊很難發現

很多大型的網站都會用到了這個


這是一個好東西,可以做委託提交,使頁面不刷新、不跳轉。


網易雲音樂 刷新網頁也能不中斷播放


推薦閱讀:

TAG:互聯網 | 前端開發 | HTML | 網站 | iframe |