首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何从服务器端强制设置IE的兼容性模式?

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

Stack Overflow用户
提问于 2018-04-11 01:03:03
回答 2查看 0关注 0票数 0

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

以下是我用来尝试了解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

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

谷歌的“定义文档兼容性”,遗憾的是垃圾邮件引擎不允许我发布超过2个网址。

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

代码语言:javascript
复制
<!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

代码语言:javascript
复制
<system.webServer>
  <httpProtocol>
    <customHeaders>
      <clear />
      <add name="X-UA-Compatible" value="IE=Edge" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

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

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

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

任何想法和我可能错过的东西?是否有可能强制IE浏览器始终呈现页面而不触发Compat模式?

EN

回答 2

Stack Overflow用户

发布于 2018-04-11 09:56:19

我发现这两种常见方式存在问题:

  1. <customHeaders>在web.config中使用自定义标头()可以使同一应用程序的不同部署具有不同的设置。我认为这是一件可能出错的事情,所以我认为如果应用程序在代码中指定它会更好。另外,IIS6不支持这一点
  2. <meta>在Web表单母版页或MVC布局页中包含HTML 标记似乎比上述内容更好。但是,如果某些页面没有从这些页面继承,那么标签需要被复制,因此存在潜在的可维护性和可靠性问题。
  3. 只需将X-UA-Compatible标题发送到Internet Explorer客户端即可减少网络流量。

结构良好的应用程序

如果应用程序的结构方式导致所有页面最终从单个根页面继承<meta>

旧版应用程序

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

代码语言:javascript
复制
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中以编程方式注册它们

代码语言:javascript
复制
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中触发。我还没有想出如何解决这个错误。
票数 0
EN

Stack Overflow用户

发布于 2018-04-11 10:20:16

将标题更改为以下内容解决了问题:

代码语言:txt
复制
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100008055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档