Wie kann man den Kompatibilitätsmodus des IE auf der Serverseite zwangsweise deaktivieren?

84

In einer domänengesteuerten Umgebung stelle ich fest, dass der Kompatibilitätsmodus auf bestimmten Clients (winXP / Win7, IE8 / IE9) ausgelöst wird, selbst wenn wir X-UA-Tags, eine! DOCTYPE-Definition und die Antwort "IE = Edge" bereitstellen Überschriften. Bei diesen Clients ist das Kontrollkästchen "Intranetsites in Kompatibilitätsansicht anzeigen" aktiviert. Welches ist genau das, was ich zu überschreiben versuche.

Im Folgenden finden Sie die Dokumentation, mit der ich versucht habe zu verstehen, wie der IE den Kompatibilitätsmodus tatsächlich auslöst.

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

Websitebesitzer haben immer die Kontrolle über ihren Inhalt. Websitebesitzer können das X-UA-kompatible Tag verwenden, um absolut aussagekräftig zu sein, wie ihre Website angezeigt werden soll, und Seiten im Standardmodus IE7-Standards zuzuordnen. Die Verwendung des X-UA-kompatiblen Tags überschreibt die Kompatibilitätsansicht auf dem Client.

Google für "Definieren der Dokumentkompatibilität" , leider lässt mich die SPAM-Engine nicht mehr als 2 URLs posten.

Dies ist eine ASP .NETWeb-App und enthält die folgenden Definitionen auf der Masterseite:

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

und web.config

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

Ich habe Fiddler verwendet, um zu überprüfen, ob der Header tatsächlich korrekt injiziert wird.

Nach meinem Verständnis sollte ich mit diesen Einstellungen die Browsereinstellung "Intranetsites in Kompatibilitätsansicht anzeigen" überschreiben können. Aber je nach Client habe ich festgestellt, dass einige von ihnen immer noch den Kompatibilitätsmodus auslösen. Es scheint auch eher auf der Computerebene eine Richtliniengruppeneinstellung zu sein, da ich unterschiedliche Ergebnisse erhalte, selbst wenn ich auf denselben Clients dieselben Anmeldeinformationen verwende.

Das Deaktivieren des Kontrollkästchens Einstellungen für die Kompatibilitätsansicht reicht aus. Der eigentliche Zweck besteht jedoch darin, sicherzustellen, dass die App unabhängig von den Clienteinstellungen genauso gerendert wird.

Irgendwelche Gedanken und was könnte mir möglicherweise fehlen? Ist es überhaupt möglich, den IE zu zwingen, die Seiten immer zu rendern, ohne den Kompatibilitätsmodus auszulösen?

tausend Dank,

Jaume

PS: Die Site befindet sich derzeit in der Entwicklung und ist natürlich nicht in der Kompatibilitätsliste von Microsoft enthalten, aber ich habe sie auch für alle Fälle überprüft.

Google für "Grundlegendes zur Liste der Kompatibilitätsansichten" . Leider lässt mich die SPAM-Engine nicht mehr als 2 URLs veröffentlichen.

JSancho
quelle

Antworten:

45

Ich habe Probleme mit den beiden gängigen Methoden gefunden:

  1. <customHeaders>Wenn Sie dies mit benutzerdefinierten Headern ( ) in web.config tun, können verschiedene Bereitstellungen derselben Anwendung diese Einstellung unterschiedlich festlegen. Ich sehe dies als eine weitere Sache, die schief gehen kann. Ich denke, es ist besser, wenn die Anwendung dies im Code angibt. Auch IIS6 unterstützt dies nicht .

  2. Das Einfügen eines HTML- <meta>Tags in eine Web Forms-Masterseite oder eine MVC-Layoutseite scheint besser zu sein als die oben genannten. Wenn jedoch einige Seiten nicht von diesen erben, muss das Tag dupliziert werden, sodass ein potenzielles Problem mit der Wartbarkeit und Zuverlässigkeit besteht.

  3. Der Netzwerkverkehr kann reduziert werden, indem der X-UA-CompatibleHeader nur an Internet Explorer-Clients gesendet wird.

Gut strukturierte Anwendungen

Wenn Ihre Anwendung so strukturiert ist, dass alle Seiten letztendlich von einer einzelnen Stammseite erben, fügen Sie das <meta>Tag wie in den anderen Antworten gezeigt ein .

Legacy-Anwendungen

Ansonsten denke ich, ist der beste Weg, dies zu tun, das automatische Hinzufügen des HTTP-Headers zu allen HTML-Antworten. Eine Möglichkeit, dies zu tun, ist die Verwendung von 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 Gibt an, dass der IE zum Rendern der Seite die neueste Rendering-Engine (anstelle des Kompatibilitätsmodus) verwenden sollte.

Es scheint, dass HTTP-Module häufig in der Datei web.config registriert sind, aber dies bringt uns zurück zum ersten Problem. Allerdings können Sie sie programmatisch in Global.asax registrieren wie folgt aus :

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

Beachten Sie, dass es wichtig ist, dass das Modul staticnicht instanziiert ist, Initdamit es nur eine Instanz pro Anwendung gibt. Natürlich sollte in einer realen Anwendung ein IoC-Container dies wahrscheinlich verwalten.

Vorteile

  • Überwindet die zu Beginn dieser Antwort beschriebenen Probleme.

Nachteile

  • Website-Administratoren haben keine Kontrolle über den Header-Wert. Dies kann ein Problem sein, wenn eine neue Version von Internet Explorer herauskommt und das Rendern der Website beeinträchtigt. Dies könnte jedoch überwunden werden, indem das Modul den Header-Wert aus der Konfigurationsdatei der Anwendung liest, anstatt einen fest codierten Wert zu verwenden.
  • Dies erfordert möglicherweise Änderungen, um mit ASP.NET MVC zu arbeiten.
  • Dies funktioniert nicht für statische HTML-Seiten.
  • Das PreSendRequestHeadersEreignis im obigen Code scheint in IIS6 nicht ausgelöst zu werden. Ich habe noch nicht herausgefunden, wie ich diesen Fehler beheben kann.
Sam
quelle
2
Es hat möglicherweise mehr als ein Jahr gedauert, bis Ihre Antwort eingegangen ist, und die eigentliche App, an der ich gearbeitet habe, ist jetzt veraltet. Trotzdem ist dies definitiv die gründlichste und am besten recherchierte Antwort, auf die ich hoffen konnte. Gute Dinge kommen zu denen, die warten :) danke Sam
JSancho
1
"Dies sollte sicherstellen, dass die Seite mit anderen Browsern konsistent und standardkonform gerendert wird." Es tut mir leid, aber das war nicht die geringste Erfahrung. Im Moment arbeite ich mit einem SSRS-Bericht, der in IE10 alles falsch macht, in Chrome einwandfrei und im IE10-Kompatibilitätsmodus nahezu einwandfrei.
BobRodes
@ BobRodes, ich glaube, ich habe das geschrieben, weil spätere Versionen von IE eher standardkonform sein sollen, aber ich habe nicht wirklich aus Erfahrung gesprochen, also guter Punkt! Ich habe gerade die Antwort aktualisiert, um diese Behauptung zu entfernen.
Sam
Microsoft verwendet in seinen Beziehungen zu seinen Konkurrenten das Konzept "Umarmen, Erweitern, Löschen". Umfassen Sie zunächst jede Art von Standard. Verbessern Sie dann den Standard mit proprietären Features und Funktionen. Lassen Sie dann die Unterstützung für den Standard in zukünftigen Versionen stillschweigend fallen. Glücklicherweise haben sie Probleme damit mit dem IE. :)
BobRodes
Dies funktionierte für mich und ich hatte verschiedene Lösungen ausprobiert, einschließlich des Meta-Tags und des Versuchs, CSS-Hacks zu verwenden, um die Bereiche der Site zu berücksichtigen, die in z.
user609926
39

Wenn Sie meinen Header auf Folgendes ändern, wird das Problem behoben:

<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
Gideon
quelle
Ich musste auch den Kundenheader zur Datei web.config hinzufügen, damit er auf dem Windows 2008-Server funktioniert
Catch22
17

Update: Weitere nützliche Informationen Was macht <meta http-equiv = "X-UA-kompatibel" content = "IE = edge">?

Vielleicht kann Ihnen diese URL helfen: Aktivieren von Browsermodi mit Doctype

Bearbeiten: Heute konnten wir die Kompatibilitätsansicht überschreiben mit: <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

Andrew
quelle
@ Balanivash Das war wirklich eine gute Lektüre, danke für den Link. Der Artikel lässt mich glauben, dass der "Kompatibilitätsmodus" aktiviert ist, da sich die Site innerhalb der Intranetzone befindet. Dies geschieht jedoch nicht konsistent, zum Beispiel: - win7, IE8, auf einem Client -> Vollstandardmodus - win7, IE8, auf einer anderen Box mit denselben Anmeldeinformationen -> Kompatibilitätsmodus Um auf der sicheren Seite zu sein I ' Ich starte auch neue Sitzungen des Browsers und setze die IE-Entwickler-Symbolleiste bei jedem Test auf die Standardwerte zurück.
JSancho
Vielleicht können Sie dies versuchen: <meta http-equiv="X-UA-Compatible" content="IE=8" />
Andrew
1
Außerdem: Wenn Ihre Webanwendung IE8 anweisen soll
Andrew
2
Eigentlich konnten wir heute die Kompatibilitätsansicht überschreiben mit:<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
Andrew
2
Vielen Dank für die Aktualisierung Ihrer Antwort. Ich denke, es wäre besser, wenn Ihre Antwort angegeben würde, IE=Edgeda es um die Deaktivierung des Kompatibilitätsmodus geht.
Sam
0

Für Node / Express-Entwickler können Sie Middleware verwenden und diese über den Server einstellen.

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