始終沒認真搞懂X-UA-Compatible IE=7跟IE=EmulateIE7有什麼不同,最近專案要步入「古今合壁」的偉大工程,把許多IE Only的活化石網頁跟HTML5網頁摻在一起做瀨尿牛丸,再不弄清楚恐會死得難看,於是查了文件做了實驗,筆記備忘。

MSDN文件 Defining document compatibility

所有IE包含三種文件模式:

  • Standard Mode(標準模式)
    努力支援最新HTLM5/CSS3/SVG等標準,但一如大家所知,不同版本IE支持程度不同
  • Quirks Mode(接縫模式)
    力求相容較早版本瀏覽器的行為 [補充資料]
    在IE9以前,Quirks Mode相容範圍的對象限於IE5.5,IE10起則擴大到HTML5規範所定義的Quirks模式。
  • Almost-Standards Mode(準標準模式)
    支援最新標準,但保有先前版本的圖形渲染行為(Graphic Rendering Behavior)
    要用"-//W3C//DTD HTML 4.0 Transitional//EN"之類的DTD觸發,不太常見,在此略過。

文件模式可透過HTTP Header、HTML <!DOCTYPE>表頭、X-UA-Compatible Metadata或IE開發者工具控制。用IE開發者工具切換的做法大家己經很熟,在此就不多說,這裡只聚焦於「如何調整HTML內容,將IE切換成想要的文件模式」。

MSDN文件 Specifying legacy document modes

HTML可從兩個地方控制文件模式,HTML最前方的<!DOCTYPE>以及X-UA-Compatible Header,而IE套用原則如下:

  • 若網頁同時有<!DOCTYPE>及X-UA-Compatible Header,以Header為準
  • 若瀏覽器支援X-UA-Compatible Header,但不支援Header指定的文件模式,將採用最高文件標準(IE=Edge)
  • 舊版瀏覽器如不支援X-UA-Compatible Header,由<!DOCTYPE>決定
  • IE9(含)以前會以IE5(Quirks) Mode顯示沒有標示<!DOCTYPE>的網頁,建議網頁一律都加<!DOCTYPE html>。

IE會以標準模式處理具有<!DOCTYPE>宣告的網頁,否則就採Quirks模式。X-UA-Compatible Header應放在<header>區前方,其前方只允許存在其他meta Header或<title>。

IE9起,內嵌FrameSet或IFrame時,網頁也只能有一種文件模式,例如:IE9模式網頁以IFrame內嵌Quirks模式網頁,IFrame網頁還是會以標準模式顯示。IE10才做了改良,允許IFrame網頁模擬Quirks模式。

X-UA-Compatible Header有以下寫法:

  1. 限制IE使用IE9/IE8/IE7模準模式
    <meta http-equiv="x-ua-compatible" content="IE=9" >
    <meta http-equiv="x-ua-compatible" content="IE=8" >
    <meta http-equiv="x-ua-compatible" content="IE=7" >
  2. EmulateIE*
    EmulateIE*的效果視<!DOCTYPE>宣告而定,若依宣告使用標準模式,則IE會依EmulateIE*決定使用IE9/8/7標準模式;若網頁缺少<!DOCTYPE>宣告進入Quirks模式,則一律改用IE5模式。
    例如:IE=EmulateIE7用在包含<!DOCTYPE>網頁效果等同IE=7,若網頁沒有<!DOCTYPE>(Quirks模式),效果等同IE=5。
    <meta http-equiv="x-ua-compatible" content="IE=EmulateIE9" >
    <meta http-equiv="x-ua-compatible" content="IE=EmulateIE8" >
    <meta http-equiv="x-ua-compatible" content="IE=EmulateIE7" >
    補充資料

了解原理,不做實驗驗證感覺不夠踏實。我找到stackoverflow的範例,很巧妙地利用Quirks模式才能識別的樣式以及圓角效果突顯文件模式,出現綠色時表示Quirks模式生效,出現圓角表示為IE9以上的文件模式。另外我還加了段檢測VBScript是否生效的橋段,看到VBScript is alive!代表支援VBScript。為方便測試,我把程式寫成ASPX,透過QueryString參數docType=Y/N決定要不要加<!DOCTYPE html>宣告,參數ie=7/8/9/10/11/Edge/EmulateIE7用來指定X-UA-Compatible Header。另外,網頁也印出navigator.userAgent字串方便觀察IE模式。

完整程式範例如下:

<%@Page Language="C#" %>
<%= Request["docType"]=="Y"?"<!DOCTYPE html>":"" %>
 
<html>
<head>
<%= !String.IsNullOrEmpty(Request["ie"])?
    "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=" + Request["ie"] + "\">" : "" %>
</head>
<body>
  <div id="vbTest">VBScript is dead!</div>
  <script type="text/vbscript">
    If IsNumeric(123) Then 
        document.getElementById("vbTest").InnerText = "VBScript is alive!"
    End If
  </script>
  <div style="background: #cf0000;background: 007f00;border-radius: 12px;padding: 12px;
          width: 400px; color: yellow">
  <ul>
    <li>In quirks mode this box is green.</li>
    <li>In IE9 mode, it's red.</li>
    <li>In quicks mode emulation, it's green but still rounded.</li>
  </ul>
  </div>
  <script type="text/javascript">
  document.write(navigator.userAgent);
  </script>
</body>
</html>

實驗結果

以下四組均加入<!DOCTYPE html>,X-UA-Compatible則分別設為IE=Edge, IE=11, IE=10, IE=9。

由於使用IE9以上標準模式,div均呈現紅色園角,IE=Edge/IE=11完全相同,不支援VBScript,userAgent無MSIE版本相容訊息。

IE=10/IE=9時,userAgent出現"comptabile; MSIE 10.0;"以及"comptabile; MSIE 9.0;",代表IE已啟用相容模式。

再來的四組也包含<!DOCTYPE html>,X-UA-Compatible分別設為IE=8, IE=7, IE=EmulateIE7, IE=5。

當文件模式降到IE9以下,圓角不見了,而userAgent有"comptabile; MSIE X.0"。比對IE=Emulate7與IE=7的效果相同,驗證先前所說「IE=EmulateIE7用在包含<!DOCTYPE>網頁效果等同IE=7」。IE=5很慘,div底色完全出不來,不愧是瀏覽器界的山頂洞人。

最後來測試Quirks模式,透過docType=N拿掉<!DOCTYPE html>,如不加X-UA-Compatible,會出現綠底圓角,證實處於Quirks模式。

若加上IE=7,依先前X-UA-Compatible優先於<!DOCTYPE>原則,進入IE7標準模式。

若加上IE=EmulateIE7,依先前理論,Quirks配上EmulateIE7等同IE=5,得到如上圖最後IE=5相同的結果。

搞完這一大串,對IE的文件模式總算進入「略懂」狀態,呼~ Orz


Comments

# by priya

There are many interesting information included and i can easily understand all given information.I post something on my blog to post something, or wait to post something worth saying. Keep update more information....

# by Leon

其實直接放生 IE 就好

# by Terry

好複雜 XDD

# by Jackson2847

黑暗大求救,我需要在 Edge 裡面:強迫網頁採用 IE mode 解析,請問該加入什麼語法? 因為舊的OCX元件是在IE 11底下跑,短期還來不及移植 QQ

# by Jeffrey

to Jackson2847,Edge 要先切到 IE 模式(手動或用企業模式網站清單),請參考這篇 https://blog.darkthread.net/blog/msedge-iemode/

# by Jackson2847

窩愛泥!!拯救我的一天~

Post a comment