¿Cómo desactivar forzosamente el modo de compatibilidad de IE desde el lado del servidor?

84

En un entorno controlado por dominio, encuentro que el modo de compatibilidad se activa en ciertos clientes (winXP / Win7, IE8 / IE9) incluso cuando proporcionamos etiquetas X-UA, una definición! DOCTYPE y una respuesta "IE = Edge" encabezados. Estos clientes tienen marcada la casilla de verificación "mostrar sitios de intranet en vista de compatibilidad". Que es precisamente lo que intento anular.

La siguiente es la documentación que he usado para intentar comprender cómo IE decide activar realmente el modo de compatibilidad.

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

Los propietarios del sitio siempre tienen el control de su contenido. Los propietarios de sitios pueden optar por utilizar la etiqueta X-UA-Compatible para ser absolutamente declarativos sobre cómo les gustaría que se muestre su sitio y para asignar las páginas del modo Estándares a los Estándares IE7. El uso de la etiqueta X-UA-Compatible anula la Vista de compatibilidad en el cliente.

Google para "Definir la compatibilidad de documentos" , lamentablemente el motor de SPAM no me permite publicar más de 2 URL.

Esta es una ASP .NETaplicación web e incluye las siguientes definiciones en la página maestra:

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

y web.config

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

He usado Fiddler para verificar que el encabezado se esté inyectando correctamente.

Tengo entendido que con esta configuración debería poder anular la configuración del navegador "Mostrar sitios de intranet en Vista de compatibilidad". Pero, dependiendo del cliente, he descubierto que algunos de ellos todavía activarán el modo de compatibilidad. También parece estar en el nivel de la máquina en lugar de una configuración de grupo de políticas, ya que obtengo resultados diferentes incluso cuando uso con el mismo conjunto de credenciales en diferentes clientes.

Deshabilitar la casilla de verificación Configuración de vista de compatibilidad funciona. Pero el propósito real es asegurarse de que la aplicación se procese exactamente de la misma manera, independientemente de la configuración del cliente.

¿Alguna idea y lo que podría estar perdiendo? ¿Es posible obligar a IE a representar siempre las páginas sin activar el modo Compat?

un millón de gracias,

Jaume

PD: el sitio está actualmente en desarrollo y, por supuesto, no está en la lista de compatibilidad de Microsoft, pero también lo he comprobado por si acaso.

Google para "Comprender la lista de vistas de compatibilidad" , lamentablemente el motor de SPAM no me permite publicar más de 2 URL.

JSancho
fuente

Respuestas:

45

Encontré problemas con las dos formas comunes de hacer esto:

  1. Hacer esto con encabezados personalizados ( <customHeaders>) en web.config permite que diferentes implementaciones de la misma aplicación tengan esta configuración de manera diferente. Veo esto como una cosa más que puede salir mal, así que creo que es mejor si la aplicación especifica esto en el código. Además, IIS6 no admite esto .

  2. Incluir una <meta>etiqueta HTML en una página maestra de formularios web o en una página de diseño MVC parece mejor que lo anterior. Sin embargo, si algunas páginas no heredan de estas, la etiqueta debe duplicarse, por lo que existe un problema potencial de mantenimiento y confiabilidad.

  3. El tráfico de red se puede reducir enviando solo el X-UA-Compatibleencabezado a los clientes de Internet Explorer.

Aplicaciones bien estructuradas

Si su aplicación está estructurada de una manera que hace que todas las páginas hereden finalmente de una sola página raíz, incluya la <meta>etiqueta como se muestra en las otras respuestas .

Aplicaciones de legado

De lo contrario, creo que la mejor manera de hacerlo es agregar automáticamente el encabezado HTTP a todas las respuestas HTML. Una forma de hacer esto es usando 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 indica que IE debería usar su último motor de renderizado (en lugar del modo de compatibilidad) para renderizar la página.

Parece que los módulos HTTP a menudo se registran en el archivo web.config, pero esto nos lleva de vuelta al primer problema. Sin embargo, puede registrarlos programáticamente en Global.asax así:

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

Tenga en cuenta que es importante que el módulo esté staticy no instanciado Initpara que solo haya una instancia por aplicación. Por supuesto, en una aplicación del mundo real, un contenedor de IoC probablemente debería gestionar esto.

Ventajas

  • Supera los problemas descritos al comienzo de esta respuesta.

Desventajas

  • Los administradores del sitio web no tienen control sobre el valor del encabezado. Esto podría ser un problema si aparece una nueva versión de Internet Explorer y afecta negativamente la representación del sitio web. Sin embargo, esto podría superarse haciendo que el módulo lea el valor del encabezado del archivo de configuración de la aplicación en lugar de usar un valor codificado.
  • Esto puede requerir modificaciones para funcionar con ASP.NET MVC.
  • Esto no funciona para páginas HTML estáticas.
  • El PreSendRequestHeadersevento en el código anterior no parece activarse en IIS6. Todavía no he descubierto cómo resolver este error.
Sam
fuente
2
Es posible que haya tardado más de un año en llegar su respuesta, y la aplicación real en la que estaba trabajando ahora está obsoleta. Sin embargo, esta es definitivamente la respuesta más completa y mejor investigada que podría haber esperado. Las cosas buenas llegan a los que esperan :) gracias Sam
JSancho
1
"Esto debería garantizar que la página se muestre de forma coherente con otros navegadores y de forma compatible con los estándares". Lo siento, pero esta no ha sido mi experiencia en lo más mínimo. En este momento, estoy trabajando con un informe SSRS que se muestra mal en IE10, muy bien en Chrome y casi bien en el modo de compatibilidad con IE10.
BobRodes
@BobRodes, creo que escribí eso porque se supone que las versiones posteriores de IE son más compatibles con los estándares, pero en realidad no estaba hablando por experiencia, ¡así que buen punto! Acabo de actualizar la respuesta para eliminar esa afirmación.
Sam
Microsoft usa un concepto de "acoger, expandir, extinguir" en sus relaciones con sus competidores. Primero, adopte cualquier tipo de estándar. Luego, "mejore" el estándar con características y funciones propietarias. Luego, abandone silenciosamente el soporte para el estándar en versiones futuras. Afortunadamente, tienen problemas con eso con IE. :)
BobRodes
Esto funcionó para mí y probé varias soluciones diferentes, incluida la metaetiqueta, e intenté usar hacks css para dar cuenta de las áreas del sitio que no se mostraban incorrectamente en ie.
user609926
39

Cambiar mi encabezado a lo siguiente resuelve el problema:

<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
Gedeón
fuente
También necesitaba agregar el encabezado del cliente al archivo web.config para que funcione en el servidor Windows 2008
Catch22
17

Actualización: más información útil ¿Qué hace <meta http-equiv = "X-UA-Compatible" content = "IE = edge">?

Quizás esta URL pueda ayudarlo: Activar modos de navegador con Doctype

Editar: hoy pudimos anular la vista de compatibilidad con: <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

Andrés
fuente
@Balanivash Esa fue una lectura realmente buena, gracias por el enlace. El artículo me lleva a creer que el "Modo de compatibilidad" está habilitado porque el sitio está ubicado dentro de la zona de la intranet. Sin embargo, esto no ocurre de manera consistente, por ejemplo: - win7, IE8, en un cliente -> modo estándar completo - win7, IE8, en una caja diferente con las mismas credenciales -> modo compat Para estar en el lado seguro I ' También estoy iniciando nuevas sesiones del navegador y restableciendo la barra de herramientas del desarrollador de IE a los valores predeterminados en cada prueba.
JSancho
Quizás puedas probar esto: <meta http-equiv="X-UA-Compatible" content="IE=8" />
Andrew
1
Además: si desea que su aplicación web le diga a IE8 que realmente confíe en usted, debe enviar X-UA-Compatible como un encabezado HTTP desde su servidor web en lugar de la metaetiqueta: social.msdn.microsoft.com/Forums/en- US / iewebdevelopment / thread /…
Andrew
2
De hecho, hoy pudimos anular la vista de compatibilidad con:<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
Andrew
2
Gracias por actualizar tu respuesta. Creo que sería mejor si su respuesta especificara, IE=Edgeya que la pregunta es sobre deshabilitar el modo de compatibilidad.
Sam
0

Para los desarrolladores de Node / Express, puede usar middleware y configurarlo a través del servidor.

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