常用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们,实在过于奇葩,不在本文范围内。
参考: