常用IE開發者工具的同窗,確定見過瀏覽器模式和文本模式,對於這兩個名詞,綜合相關文檔解釋以下: html
瀏覽器模式(Browser Mode),用於切換IE針對該網頁的默認文本模式、對不一樣版本瀏覽器的條件註釋解析、決定請求頭裏userAgent的值。它在瀏覽器發出請求以前就已經肯定,網站沒有辦法修改這個值。它表明的是用戶以何種瀏覽器訪問網站。IE9支持下列瀏覽器模式: web
userAgent | 默認文本模式 | |
---|---|---|
IE7 | MSIE 7.0 | IE7標準 |
IE8 | MSIE 8.0 && Trident/4.0 | IE8標準 |
IE9 | MSIE 9.0 && Trident/5.0 | IE9標準 |
IE9兼容性 | MSIE 7.0 && Trident/5.0 | IE7標準 |
(IE9兼容性模式與IE7模式的區別是:前者在UA里加上了Trident版本,後者和IE7徹底一致無Trident標識;IE8中,IE9兼容性模式對應爲IE8兼容性模式,UA裏Trident版本爲4.0,其餘沒變化。另,IE8中沒有IE9模式) 瀏覽器
文本模式(Document Mode),其實就是常常說的文檔模式。不一樣的文本模式對應不一樣的排版引擎,不一樣的JS引擎。上面提到,每一種瀏覽器模式對應一種默認的文本模式,網站還能夠經過一些手段來更改文本模式,它表明的是瀏覽器以何種模式呈現頁面。IE9有下列文本模式: 服務器
documentMode | |
---|---|
IE7標準 | 7 |
IE8標準 | 8 |
IE9標準 | 9 |
怪異(Quirks) | 5 |
(須要說明的是,IE8開始支持的渲染機制有:怪異模式(quirks mode)、徹底標準模式(standards mode)和近似標準模式(almost standards mode),但開發者工具是沒法選擇近似標準模式的,實際上咱們通常都選擇觸發徹底標準模式) ide
用來解決IE各版本帶來的兼容性問題。根據微軟描述的IE兼容性策略,在IE8+訪問一個頁面要通過這樣的流程: 工具
1、首先,瀏覽器要肯定瀏覽器模式。上面說過,瀏覽器模式是在請求發送以前就必須肯定,默認取最新(IE9爲IE9標準,IE8爲IE8標準),有兩種方式能夠更改它: 測試
2、瀏覽器經過請求頭裏userAgent的值,告訴服務器當前是何種瀏覽器模式; 網站
3、服務器能夠經過下面方式改變瀏覽器文本模式: ui
4、瀏覽器綜合考慮開發者工具設置、第三步服務器返回的設置、兼容性列表設置等等狀況,決定頁面使用何種文本模式。這個過程有點複雜,放一張Qwrap羣裏灰大提供的流程圖,能夠本身點開看大圖。 spa
(上圖是IE9選取文本模式的流程圖,這裏還有IE8版本,有一些區別)
回顧下前面的介紹,瀏覽器模式決定:1)發送給服務端的UA;2)默認的文本模式;3)如何解析條件註釋。它在請求發送前就已經肯定,且不受服務端控制。文本模式決定:1)排版引擎;2)JS引擎。它在瀏覽器獲得響應後最終肯定,服務端可經過doctype或X-UA-Compatible來控制。
測試1、根據前文,若是用戶瀏覽器沒有激活兼容性視圖;沒有開啓IE開發者工具。那麼IE9的瀏覽器模式默認爲IE9,默認對應的文本模式應該是IE9標準(對於IE8來講,是相似的),咱們經過下列代碼將它改到IE7標準:
<meta http-equiv="X-UA-Compatible" content="IE=7">
|
下面,咱們分別用原生IE八、IE9測試這個頁面:
請求頭UA | navigator.userAgent | 條件註釋 | documentMode | JS引擎 | |
---|---|---|---|---|---|
IE8 | MSIE 8.0 && Trident/4.0 |
MSIE 8.0 && Trident/4.0 | IE7 | 7 | IE7 |
IE9 | MSIE 9.0 && Trident/5.0 | MSIE 7.0 && Trident/5.0 | IE7 | 7 | IE7 |
上表說明,瀏覽器發送請求時的瀏覽器模式符合預期(根據請求頭UA),X-UA-Compatible確實會將瀏覽器文本模式改到了IE7標準(根據documentMode和JS引擎)。奇怪的是,文本模式的改變致使了瀏覽器模式的改變,由於條件註釋是由瀏覽器模式決定的。本例中,文本模式改到IE7標準,條件註釋也跟着變成IE7,意味着瀏覽器模式變到IE9/IE8兼容性(從IE9的測試來看,不能是IE7,由於UA裏包含Trident)。至於IE8中JS取到的UA爲何沒有變化,多是bug或者理解不一致。
測試2、那若是把測試地址加到兼容性列表呢?根據前文,這種狀況瀏覽器模式應該是IE9/IE8兼容性,對應的文本模式依然是IE7標準。測試結果以下:
請求頭UA | navigator.userAgent | 條件註釋 | documentMode | JS引擎 | |
---|---|---|---|---|---|
IE8 | MSIE 7.0 && Trident/4.0 | MSIE 7.0 && Trident/4.0 | IE7 | 7 | IE7 |
IE9 | MSIE 7.0 && Trident/5.0 | MSIE 7.0 && Trident/5.0 | IE7 | 7 | IE7 |
上表是徹底符合預期的。
測試3、若是把X-UA-Compatible改爲IE=edge,繼續使用兼容性模式測試呢?結論以下:
請求頭UA | navigator.userAgent | 條件註釋 | documentMode | JS引擎 | |
---|---|---|---|---|---|
IE8 | MSIE 7.0 && Trident/4.0 |
MSIE 7.0 && Trident/4.0 | IE8 | 8 |
IE8 |
IE9 | MSIE 7.0 && Trident/5.0 | MSIE 9.0 && Trident/5.0 |
IE9 | 9 |
IE9 |
這個結論其實跟測試一是一致的:X-UA-Compatible爲IE=edge,意味着文本模式會使用最新可用的版本,然而文本模式的更改,又把瀏覽器模式從IE9/IE8兼容性變成IE9/IE8。IE9會按照新的瀏覽器模式來設置JS的navigator.userAgent,IE8下JS的UA不變。
測試4、那若是經過開發者工具人爲設置瀏覽器模式和文本模式呢?通過測試,這樣測試都是符合預期的。例如IE9下,設置瀏覽器模式爲IE8,文本模式爲IE7標準,請求頭UA、JS的UA、條件註釋都代表瀏覽器模式是IE8,documentMode和JS引擎都代表文本模式是IE7標準。由於,IE開發者工具的優先級最高,設置了這個,其餘條件通通無視!
IE8/9中X-UA-Compatible對文本模式的改變會致使瀏覽器模式的改變,也就是說服務端能夠間接控制瀏覽器模式。這與微軟文檔裏這一段描述有出入:
An important detail to remember is that Browser Mode is chosen before IE requests web content. This means that sites cannot choose a Browser Mode.
對於IE8,若是網站經過X-UA-Compatible meta/header更改文本模式爲當前瀏覽器模式默認文本模式以外的值,那麼頁面將按照新的文本模式來呈現,條件註釋也按照新的文本模式對應的瀏覽器模式來解析,可是JS獲取的UA是瀏覽器模式初始狀態。這樣會致使用JS獲取UA獲得的瀏覽器版本,與實際渲染的瀏覽器版本不符,這會對基於UA的瀏覽器檢測形成干擾。
對於IE9,只有一點與IE8不一樣:JS獲取到的是新文本模式對應的瀏覽器模式的UA。這會致使用JS獲取UA獲得的瀏覽器版本,與請求頭髮送給服務器UA裏標識的瀏覽器版本不符,這可能對統計有影響。
對於IE這種兼容性方案,幾乎不可能作到理論上的完美。我的感受仍是IE9的策略影響面較小,更好一些。
PS,上述結論都是我用Windows XP的原生IE8,Windows 7的原生IE9親自測試得出來的。對於國內那些IE Shell們,實在過於奇葩,不在本文範圍內。
參考: