Comment désactiver avec force le mode de compatibilité d'IE du côté serveur?

84

Dans un environnement contrôlé par domaine, je constate que le mode de compatibilité est déclenché 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. Ces clients ont la case à cocher «Afficher les sites intranet en vue de compatibilité» cochée. C'est précisément ce que j'essaie de passer outre.

Ce qui suit est la documentation que j'ai utilisée pour essayer de comprendre comment IE décide de déclencher réellement 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 sites peuvent choisir d'utiliser la balise compatible X-UA pour être absolument déclaratifs sur la façon dont ils aimeraient que leur site s'affiche et pour mapper les pages du mode Standards aux normes IE7. L'utilisation de la balise compatible X-UA remplace la vue de compatibilité sur le client.

Google pour "Defining Document Compatibility" , malheureusement le moteur SPAM ne me laisse pas publier plus de 2 URL.

Ceci est une ASP .NETapplication Web et inclut les définitions suivantes sur 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 bien injecté correctement.

Je crois comprendre qu'avec ces paramètres, je devrais pouvoir remplacer le paramètre du navigateur "Afficher les sites intranet dans l'affichage de compatibilité". Mais selon le client, j'ai constaté que certains d'entre eux déclencheraient toujours le mode de compatibilité. Cela semble également être au niveau de la machine plutôt qu'un paramètre de groupe de stratégies, car j'obtiens des résultats différents même lorsque j'utilise avec le même ensemble d'informations d'identification sur différents clients.

La désactivation de la case à cocher Paramètres d'affichage de compatibilité fait l'affaire. Mais le but 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 manquer? Est-il possible du tout de forcer IE à toujours rendre les pages sans déclencher le mode de compatibilité?

mille mercis,

Jaume

PS: le site est actuellement en développement et n'est bien sûr pas dans la liste de compatibilité de Microsoft, mais j'ai aussi 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.

JSancho
la source

Réponses:

45

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

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

  2. Inclure une <meta>balise HTML dans une page maître Web Forms ou une page de mise en page MVC semble mieux que ce qui précède. Cependant, si certaines pages n'en héritent pas, la balise doit être dupliquée, il existe donc un problème potentiel de maintenabilité et de fiabilité.

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

Applications bien structurées

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

Applications héritées

Sinon, je pense que la meilleure façon de faire est d'ajouter automatiquement l'en-tête HTTP à toutes les réponses HTML. Une façon de procéder consiste à utiliser un 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 rendre 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 staticet non instancié dans Initafin 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 évoqués au début de cette réponse.

Désavantages

  • Les administrateurs du site Web n'ont aucun contrôle sur la valeur de l'en-tête. Cela peut poser problème si une nouvelle version d'Internet Explorer sort et affecte négativement le rendu du site Web. Cependant, cela pourrait être surmonté en demandant au module de lire la valeur d'en-tête à partir du fichier de configuration de l'application au lieu d'utiliser une valeur codée en dur.
  • Cela peut nécessiter une modification pour fonctionner avec ASP.NET MVC.
  • Cela ne fonctionne pas pour les pages HTML statiques.
  • L' PreSendRequestHeadersévénement dans le code ci-dessus ne semble pas se déclencher dans IIS6. Je n'ai pas encore trouvé comment résoudre ce bug.
Sam
la source
2
Votre réponse a peut-être pris plus d'un an, et l'application sur laquelle je travaillais est désormais obsolète. Néanmoins, c'est certainement la réponse la plus approfondie et la mieux documentée que j'aurais pu espérer. De bonnes choses arrivent à ceux qui attendent :) merci Sam
JSancho
1
"Cela devrait garantir que la page est affichée de manière cohérente avec les autres navigateurs et d'une manière conforme aux normes." Je suis désolé, mais cela n'a pas du tout été mon expérience. En ce moment, je travaille avec un rapport SSRS qui rend tout faux dans IE10, très bien dans Chrome, et à peu près bien en mode de compatibilité IE10.
BobRodes
@BobRodes, je pense avoir écrit cela parce que les versions ultérieures d'IE sont censées être plus conformes aux normes, mais je ne parlais pas vraiment d'expérience, donc bon point! Je viens de mettre à jour la réponse pour supprimer cette réclamation.
Sam
Microsoft utilise un concept «embrasser, étendre, éteindre» dans ses relations avec ses concurrents. Tout d'abord, adoptez toute sorte de norme. Ensuite, «améliorez» la norme avec des fonctionnalités et des fonctions propriétaires. Ensuite, supprimez discrètement la prise en charge de la norme dans les versions futures. Heureusement, ils ont des problèmes avec IE. :)
BobRodes
Cela a fonctionné pour moi et j'ai essayé plusieurs solutions différentes, y compris la balise meta et en essayant d'utiliser des hacks css pour tenir compte des zones du site qui n'étaient pas rendues incorrectement dans ie.
user609926
39

Changer mon en-tête pour résoudre le problème:

<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
Gédéon
la source
J'avais également besoin d'ajouter l'en-tête client au fichier web.config pour le faire fonctionner sur le serveur Windows 2008
Catch22
17

Mise à jour: informations plus utiles Que fait <meta http-equiv = "X-UA-Compatible" content = "IE = edge">?

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

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

Andrew
la source
@Balanivash C'était une très bonne lecture en fait, merci pour le lien. L'article m'amène à croire que le "mode de compatibilité" est activé car le site se trouve dans la zone intranet. Cependant, cela ne se produit pas de manière cohérente, par exemple: - win7, IE8, sur un client -> mode standard complet - win7, IE8, sur un boîtier différent avec les mêmes informations d'identification -> mode compat Pour être du bon côté I ' Je lance également de nouvelles sessions du navigateur et réinitialise la barre d'outils du développeur IE aux valeurs par défaut à chaque test.
JSancho
Peut-être que vous pouvez essayer ceci: <meta http-equiv="X-UA-Compatible" content="IE=8" />
Andrew
1
Aussi: si vous voulez que votre application Web dise à IE8 de vous faire vraiment confiance, vous devez envoyer X-UA-Compatible en tant qu'en-tête HTTP depuis votre serveur Web au lieu de la balise meta: social.msdn.microsoft.com/Forums/en- US / iewebdevelopment / thread /…
Andrew
2
En fait, aujourd'hui, nous avons pu annuler la vue de compatibilité avec:<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
Andrew
2
Merci d'avoir mis à jour votre réponse. Je pense qu'il serait préférable que votre réponse soit spécifiée IE=Edgepuisque la question concerne la désactivation du mode de compatibilité.
Sam
0

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

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