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


84

在域控制的环境中,我发现即使在我们提供X-UA标签,!DOCTYPE定义和“ IE = Edge”响应的情况下,某些客户端(winXP / Win7,IE8 / IE9)也会触发兼容模式标头。这些客户端已选中“在兼容性视图中显示Intranet站点”复选框。这正是我要覆盖的内容。

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

http://msdn.microsoft.com/zh-cn/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

网站所有者始终可以控制其内容。网站所有者可以选择使用X-UA-Compatible标记来绝对声明他们希望其网站如何显示以及如何将Standards模式页面映射到IE7 Standard。使用X-UA-Compatible标签会覆盖客户端上的“兼容性视图”。

Google表示“定义文档兼容性”,但不幸的是,SPAM引擎不允许我发布两个以上的网址。

这是一个ASP .NETWeb应用程序,在母版页上包含以下定义:

<!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站点”浏览器设置。但是根据客户端的不同,我发现其中一些仍会触发兼容模式。这似乎还取决于计算机级别,而不是策略组设置,因为即使在不同客户端上使用同一组凭据时,我也会获得不同的结果。

禁用“兼容性视图设置”复选框可以解决问题。但是实际目的是确保无论客户端设置如何,应用程序的渲染方式都完全相同。

有什么想法,我可能会错过什么?是否有可能迫使IE始终呈现页面而不触发Compat模式?

太感谢了,

久美

PS:该站点目前正在开发中,当然不在Microsoft的兼容性列表中,但我也进行了检查,以防万一。

Google表示“了解兼容性视图列表”,但不幸的是,SPAM引擎不允许我发布两个以上的网址。

Answers:


45

我发现两种常见的执行方法存在问题:

  1. 使用<customHeaders>web.config中的自定义标头()进行此操作可以使同一应用程序的不同部署具有不同的设置。我认为这可能会出错,因此,如果应用程序在代码中指定此内容,则更好。此外,IIS6不支持this

  2. <meta>在Web窗体母版页或MVC布局页中包括HTML标记似乎比上述方法更好。但是,如果某些页面没有继承自这些页面,则需要复制标签,因此存在潜在的可维护性和可靠性问题。

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

结构合理的应用

如果您的应用程序的结构导致所有页面最终都继承自单个根页面,则请包含其他答案中<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容器可能应该对此进行管理。

好处

  • 克服了此答案开头概述的问题。

缺点

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

2
您的答案可能要花一年多的时间,而我正在使用的实际应用程序现在已过时。但是,这绝对是我所希望的最彻底,研究最彻底的答案。那些等待的人会
感到高兴

1
“这应该确保页面与其他浏览器一致并且以符合标准的方式呈现。” 很抱歉,但这至少不是我的经验。现在,我正在处理一个SSRS报告,该报告会在IE10中呈现所有错误,在Chrome中显示良好,在IE10兼容模式下也呈现良好状态。
BobRodes

@BobRodes,我想我写这封信是因为更高版本的IE应该更符合标准,但是我并不是从经验上讲的,所以很好!我刚刚更新了答案以删除该声明。
山姆

微软在与竞争对手的关系中使用“拥抱,扩展,消灭”的概念。首先,采用任何标准。然后,通过专有特性和功能“改进”标准。然后,在将来的版本中悄悄放弃对标准的支持。幸运的是,他们在使用IE时遇到了麻烦。:)
BobRodes 2014年

这对我有用,并且我尝试了几种不同的解决方案,包括meta标记,并尝试使用css hacks来解决未在ie中正确呈现的网站区域。
user609926

39

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

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

我还需要将客户标头添加到web.config文件中,以便使其在Windows 2008服务器上工作
Catch22 '16

17

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

也许这个网址可以帮助您: 使用Doctype激活浏览器模式

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


@Balanivash实际上,这是一个非常好的阅读,感谢您的链接。这篇文章使我相信,由于站点位于Intranet区域内,因此已启用“兼容模式”。但是,这种情况并不会持续发生,例如:-在客户端上运行win7,IE8->完全标准模式-在具有相同凭据的不同机器上运行win7,IE8->兼容模式为了安全起见,我' m还会启动浏览器的新会话,并在每次测试时将IE开发人员工具栏重置为默认值。
JSancho

也许您可以尝试以下方法: <meta http-equiv="X-UA-Compatible" content="IE=8" />
Andrew

1
另外:如果您希望您的Web应用程序告诉IE8真正信任您,则需要从Web服务器发送X-UA-Compatible作为HTTP标头而不是元标记:social.msdn.microsoft.com/Forums/en-美国/ iewebdevelopment / thread /…
安德鲁

2
实际上,今天我们可以使用以下方法覆盖兼容性视图:<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
Andrew

2
感谢您更新答案。我认为最好指定您的答案,IE=Edge因为问题是关于禁用兼容模式的。
山姆

0

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

app.use(function(req, res, next) {
  res.setHeader('X-UA-Compatible', 'IE=edge');
  next();
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.