如何从服务器端强制设置IE的兼容模式?

在一个域控制的环境中,我发现即使我们提供了X-UA标签,!DOCTYPE定义和“IE = Edge”响应,某些客户端(winXP / Win7,IE8 / IE9)也会触发兼容模式头。 这些客户端在“兼容性视图中显示Intranet站点”checkbox打勾。 这正是我想要重写的。

以下是我用来尝试了解IE如何决定实际触发兼容模式的文档。

http://msdn.microsoft.com/en-us/library/ff406036%28v=VS.85%29.aspx

http://blogs.msdn.com/b/ie/archive/2009/02/16/just-the-facts-recap-of-compatibility-view.aspx

网站所有者总是在控制其内容。 网站所有者可以select使用X-UA兼容标签来绝对声明他们希望自己的网站显示的内容,并将标准模式页面映射到IE7标准。 使用X-UA兼容标签将覆盖客户端上的兼容性视图。

谷歌的“定义文档兼容性” ,不幸的是垃圾邮件引擎不让我发布超过2个url。

这是一个ASP .NET Web应用程序,在主页上包含以下定义:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> </head> 

web.config

 <system.webServer> <httpProtocol> <customHeaders> <clear /> <add name="X-UA-Compatible" value="IE=Edge" /> </customHeaders> </httpProtocol> </system.webServer> 

我已经使用Fiddler来检查头确实被正确注入。

我的理解是,通过这些设置,我应该可以覆盖“在兼容性视图中显示Intranet站点”浏览器设置。 但是根据客户端的不同,我发现其中的一些仍然会触发兼容模式。 这也似乎是机器级别而不是策略组设置,因为即使在不同的客户机上使用相同的凭据集时,我也会得到不同的结果。

禁用“兼容性视图设置”checkbox可以做到这一点。 但实际目的是确保应用程序呈现完全相同的方式,无论客户端设置。

任何想法和我可能会失踪? 是否有可能迫使IE浏览器总是呈现页面而不触发“同步”模式?

太感谢了,

乌梅

PS:该网站目前正在开发中,当然不在微软的兼容性列表中,但我也检查过,以防万一。

谷歌的“了解兼容性查看列表” ,遗憾的是垃圾邮件引擎不让我发布超过2个url。

我发现这样做的两种常见方式的问题:

  1. 在web.config中使用自定义标题( <customHeaders> )执行此操作可以使同一应用程序的不同部署具有不同的设置。 我认为这是一件可能出错的事情,所以我认为应用程序在代码中指定它会更好。 另外, IIS6不支持这个 。

  2. 在Web窗体母版页或MVC布局页面中包含HTML <meta>标签似乎比上述要好。 但是,如果某些页面没有从这些页面inheritance,那么标签需要被复制,因此存在潜在的可维护性和可靠性问题。

  3. 仅通过将X-UA-Compatible标头发送到Internet Explorer客户端,可以减lessnetworkingstream量。

结构良好的应用程序

如果您的应用程序的结构使得所有页面最终从单个根页面inheritance,请按照其他答案中所示包含<meta>标签。

传统应用程序

否则,我认为最好的办法就是自动将HTTP头添加到所有的HTML响应中。 一种方法是使用IHttpModule

 public class IeCompatibilityModeDisabler : IHttpModule { public void Init(HttpApplication context) { context.PreSendRequestHeaders += (sender, e) => DisableCompatibilityModeIfApplicable(); } private void DisableCompatibilityModeIfApplicable() { if (IsIe && IsPage) DisableCompatibilityMode(); } private void DisableCompatibilityMode() { var response = Context.Response; response.AddHeader("X-UA-Compatible", "IE=edge"); } private bool IsIe { get { return Context.Request.Browser.IsBrowser("IE"); } } private bool IsPage { get { return Context.Handler is Page; } } private HttpContext Context { get { return HttpContext.Current; } } public void Dispose() { } } 

IE=edge表示IE应该使用其最新的渲染引擎(而不是兼容模式)来渲染页面。

HTTP模块似乎经常在web.config文件中注册,但是这使我们回到了第一个问题。 但是, 您可以像这样在Global.asax中以编程方式注册它们 :

 public class Global : HttpApplication { private static IeCompatibilityModeDisabler module; void Application_Start(object sender, EventArgs e) { module = new IeCompatibilityModeDisabler(); } public override void Init() { base.Init(); module.Init(this); } } 

请注意,模块是static并且在Init没有实例化,这对于每个应用程序只有一个实例是非常重要的。 当然,在现实世界的应用程序中,IoC容器应该可以pipe理这个。

优点

  • 克服在这个答案的开始概述的问题。

缺点

  • 网站pipe理员无法控制标题值。 如果新版本的Internet Explorer出现并对网站的呈现产生不利影响,则这可能是个问题。 但是,这可以通过让模块从应用程序的configuration文件中读取标题值而不是使用硬编码值来解决。
  • 这可能需要修改才能使用ASP.NET MVC。
  • 这不适用于静态HTML页面。
  • 上面的代码中的PreSendRequestHeaders事件似乎不会在IIS6中触发。 我还没有想出如何解决这个错误呢。

将我的标题更改为以下解决问题:

 <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> 

更新:更有用的信息<meta http-equiv =“X-UA-Compatible”content =“IE = edge”>是做什么的?

也许这个url可以帮助你: 使用Doctype激活浏览器模式

编辑:今天我们能够覆盖兼容性视图: <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

对于Node / Express开发人员,您可以使用中间件并通过服务器进行设置。

 app.use(function(req, res, next) { res.setHeader('X-UA-Compatible', 'IE=edge'); next(); });