How to forcefully set IE's Compatibility Mode off from the server-side?
Asked Answered
G

4

84

In a domain-controlled environment I'm finding that the compatibility mode is triggered on certain clients (winXP/Win7, IE8/IE9) even when we are providing a X-UA tags, a !DOCTYPE definition and "IE=Edge" response headers. These clients have the "display intranet sites in compatibility view" checkbox ticked. Which is precisely what I'm trying to override.

The following is the documentation that I've used to try understand how IE decides to actually trigger the compatibility mode.

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

Site owners are always in control of their content. Site owners can choose to use the X-UA-Compatible tag to be absolutely declarative about how they’d like their site to display and to map Standards mode pages to IE7 Standards. Use of the X-UA-Compatible tag overrides Compatibility View on the client.

This is an ASP.NET web app and includes the following definitions on the master page:

<!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>

and web.config

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

I've used Fiddler to check that the header is indeed being injected correctly.

My understanding is that with these settings I should be able override the "Display intranet sites in Compatibility View" browser setting. But depending on the client I've found that some of them will still trigger compatibility mode. It also seems to be down to the machine level rather a policy group setting, since I obtain different results even when I use with the same set of credentials on different clients.

Disabling the Compatibility View Settings checkbox does the trick. But the actual purpose is to make sure that the app is rendered exactly the same way regardless of the client settings.

Any thoughts and what I could be possibly missing? Is it possible at all to force IE to always render the pages without triggering Compat mode?

The site is currently in development and is of course not in Microsoft's compatibility list, but I've also checked just in case.

Guan answered 1/7, 2011 at 10:30 Comment(0)
G
46

I found problems with the two common ways of doing this:

  1. Doing this with custom headers (<customHeaders>) in web.config allows different deployments of the same application to have this set differently. I see this as one more thing that can go wrong, so I think it's better if the application specifies this in code. Also, IIS6 doesn't support this.

  2. Including an HTML <meta> tag in a Web Forms Master Page or MVC Layout Page seems better than the above. However, if some pages don't inherit from these then the tag needs to be duplicated, so there's a potential maintainability and reliability problem.

  3. Network traffic could be reduced by only sending the X-UA-Compatible header to Internet Explorer clients.

Well-Structured Applications

If your application is structured in a way that causes all pages to ultimately inherit from a single root page, include the <meta> tag as shown in the other answers.

Legacy Applications

Otherwise, I think the best way to do this is to automatically add the HTTP header to all HTML responses. One way to do this is using an 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 indicates that IE should use its latest rendering engine (rather than compatibility mode) to render the page.

It seems that HTTP modules are often registered in the web.config file, but this brings us back to the first problem. However, you can register them programmatically in Global.asax like this:

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);
    }
}

Note that it is important that the module is static and not instantiated in Init so that there is only one instance per application. Of course, in a real-world application an IoC container should probably be managing this.

Advantages

  • Overcomes the problems outlined at the start of this answer.

Disadvantages

  • Website admins don't have control over the header value. This could be a problem if a new version of Internet Explorer comes out and adversely affects the rendering of the website. However, this could be overcome by having the module read the header value from the application's configuration file instead of using a hard-coded value.
  • This may require modification to work with ASP.NET MVC.
  • This doesn't work for static HTML pages.
  • The PreSendRequestHeaders event in the above code doesn't seem to fire in IIS6. I haven't figured out how to resolve this bug yet.
Grilse answered 21/5, 2013 at 0:18 Comment(5)
It might have taken more than a year for your answer to come around, and the actual app that I was working on is now deprecated. Nevertheless, this is definitely the most thorough and well-researched answer that I could have hoped for. Good things come to those who wait :) thanks SamGuan
"This should ensure the page is rendered consistently with other browsers and in a standards-compliant manner." I'm sorry, but this has not been my experience in the least. Right now, I'm working with a SSRS report that renders all wrong in IE10, just fine in Chrome, and just about fine in IE10 compatibility mode.Immunotherapy
@BobRodes, I think I wrote that because later versions of IE are supposed to be more standards-compliant, but I wasn't really speaking from experience, so good point! I just updated the answer to remove that claim.Grilse
Microsoft uses a concept of "embrace, expand, extinguish" in its relations with its competitors. First, embrace any sort of standard. Then, "improve" on the standard with proprietary features and functions. Then, quietly drop support for the standard in future versions. Fortunately, they are having trouble with that with IE. :)Immunotherapy
This worked for me and I'd tried several different solutions including the meta tag and attempting to use css hacks to account for the areas of the site that weren't rendering incorrectly in ie.Bashaw
S
39

Changing my header to the following solve the problem:

<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
Slotnick answered 4/4, 2012 at 13:19 Comment(1)
I also needed to add the customer header to the web.config file to get it to work on Windows 2008 serverEstivate
M
17

Maybe this URL can help you: Activating Browser Modes with Doctype

You can override the compatibility view with: <meta http-equiv="X-UA-Compatible" content="IE=Edge" />

More useful information What does <meta http-equiv="X-UA-Compatible" content="IE=edge"> do?

Mckeehan answered 1/7, 2011 at 11:33 Comment(7)
@Balanivash That was a really good read actually, thanks for the link. The article leads me to believe the "Compatibility Mode" is being enabled because the site is located within the intranet zone. However, this is not occurring consistently, for instance: - win7, IE8, on a client -> full standards mode - win7, IE8, on a different box with the same credentials -> compat mode To be on the safe-side I'm also starting new sessions of the browser and resetting the IE developer toolbar to default values on every test.Guan
Maybe you can try this: <meta http-equiv="X-UA-Compatible" content="IE=8" />Mckeehan
Also: If you want your web application to tell IE8 to really trust you, you need to send X-UA-Compatible as an HTTP header from your web server instead of meta tag: social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/…Mckeehan
The site uses css3 if the client is capable and the IE=Edge setting is working as far as switching to IE9 or IE8 standards depending on the client. It's the "compatibility mode" that it's bothering me. And the HTTP header is actually in. That's set with the web.config options above and Fiddler does pick it the header response.Guan
Tried <add name="X-UA-Compatible" value="IE=8" /> yet?Mckeehan
Actually today we were able to override the compatibility view with: <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />Mckeehan
Thanks for updating your answer. I think it would be better if your answer specified IE=Edge since the question is about disabling compatibility mode.Grilse
S
0

For Node/Express developers you can use middleware and set this via server.

app.use(function(req, res, next) {
  res.setHeader('X-UA-Compatible', 'IE=edge');
  next();
});
Satisfy answered 10/6, 2017 at 9:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.