web-dev-qa-db-fra.com

Comment désactiver avec force le mode de compatibilité d'IE sur le serveur?

Dans un environnement contrôlé par un domaine, je constate que le mode de compatibilité est activé sur certains clients (WinXP/Win7, IE8/IE9), même lorsque nous fournissons des balises X-UA, une définition! DOCTYPE et une réponse "IE = Edge". en-têtes. La case "Afficher les sites intranet en vue de compatibilité" est cochée pour ces clients. Ce qui est précisément ce que j'essaie de remplacer.

Voici la documentation que j'ai utilisée pour essayer de comprendre comment IE décide de déclencher le mode de compatibilité.

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

Les propriétaires de sites contrôlent toujours leur contenu. Les propriétaires de site peuvent choisir d’utiliser la balise X-UA-Compatible pour indiquer de manière absolue comment leur site doit s’afficher et pour mapper les pages du mode Standards aux normes IE7. L'utilisation de la balise X-UA-Compatible annule l'affichage de compatibilité sur le client.

Google pour "Définition de la compatibilité des documents", malheureusement, le moteur anti-spam ne me permet pas de publier plus de 2 URL.

Il s'agit d'une application Web ASP .NET qui inclut les définitions suivantes dans la page maître:

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

et web.config

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

J'ai utilisé Fiddler pour vérifier que l'en-tête est effectivement injecté correctement.

D'après ce que j'ai compris, ces paramètres devraient pouvoir remplacer le paramètre de navigateur "Afficher les sites intranet en mode d'affichage de compatibilité". Mais, en fonction du client, certains d'entre eux déclencheront toujours le mode de compatibilité . Il semble également que ce soit au niveau de la machine plutôt que d'un paramètre de groupe de règles, car j'obtiens des résultats différents même lorsque j'utilise le même ensemble de références sur différents clients.

Désactiver la case à cocher Paramètres d'affichage de compatibilité fait l'affaire. Mais l'objectif réel est de s'assurer que l'application est rendue exactement de la même manière, quels que soient les paramètres du client.

Des pensées et ce que je pourrais éventuellement manquer? Est-il possible de forcer IE à toujours restituer les pages sans déclencher le mode Compat? 

merci un million,

Jaume

PS: le site est actuellement en développement et ne fait bien sûr pas partie de la liste de compatibilité de Microsoft, mais j'ai également vérifié au cas où.

Google pour "Comprendre la liste d'affichage de compatibilité", malheureusement, le moteur anti-spam ne me permet pas de publier plus de 2 URL.

83
JSancho

J'ai trouvé des problèmes avec les deux façons courantes de le faire:

  1. Faire cela avec des en-têtes personnalisés (<customHeaders>) dans web.config permet à différents déploiements de la même application de définir cela différemment. Je vois cela comme une dernière chose qui peut mal tourner, alors je pense que c'est mieux si l'application le spécifie dans le code. En outre, IIS6 ne prend pas en charge ceci .

  2. L'inclusion d'une balise HTML <meta> dans une page maître Web Forms ou une page de mise en page MVC semble meilleure que la précédente. Cependant, si certaines pages n'héritent pas de celles-ci, la balise doit être dupliquée, ce qui pose un problème potentiel de maintenabilité et de fiabilité.

  3. Le trafic réseau pourrait être réduit en envoyant uniquement l'en-tête X-UA-Compatible aux clients Internet Explorer.

Applications bien structurées

Si votre application est structurée de manière à ce que toutes les pages héritent d'une seule page racine, incluez la balise <meta> comme indiqué dans les autres réponses .

Applications héritées

Sinon, je pense que la meilleure façon de le faire est d’ajouter automatiquement l’en-tête HTTP à toutes les réponses HTML. Une façon de le faire utilise une 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 indique que IE doit utiliser son dernier moteur de rendu (plutôt que le mode de compatibilité) pour restituer la page.

Il semble que les modules HTTP soient souvent enregistrés dans le fichier web.config, mais cela nous ramène au premier problème. Cependant, vous pouvez les enregistrer par programme dans Global.asax comme ceci:

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

Notez qu'il est important que le module soit static et non instancié dans Init afin qu'il n'y ait qu'une seule instance par application. Bien sûr, dans une application réelle, un conteneur IoC devrait probablement gérer cela.

Avantages

  • Surmonte les problèmes décrits au début de cette réponse.

Désavantages

  • Les administrateurs de site Web n'ont aucun contrôle sur la valeur de l'en-tête. Cela pourrait poser problème si une nouvelle version d'Internet Explorer est disponible et affecte négativement le rendu du site Web. Cependant, ceci pourrait être surmonté en demandant au module de lire la valeur d'en-tête du fichier de configuration de l'application au lieu d'utiliser une valeur codée en dur.
  • Cela peut nécessiter des modifications pour fonctionner avec ASP.NET MVC.
  • Cela ne fonctionne pas pour les pages HTML statiques.
  • L'événement PreSendRequestHeaders dans le code ci-dessus ne semble pas se déclencher dans IIS6. Je n'ai pas encore trouvé comment résoudre ce bug.
44
Sam

Changer mon en-tête comme suit résout le problème:

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

Mise à jour: informations complémentaires Que fait <meta http-equiv = "Compatible X-UA" content = "IE = Edge">?

Peut-être que cette URL peut vous aider: Activer les modes de navigation avec Doctype

Edit: Aujourd'hui, nous avons pu remplacer la vue de compatibilité par: <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

17
Andrew

Pour les développeurs Node/Express, vous pouvez utiliser un middleware et le définir via un serveur.

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