JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

Problemas para detectar Internet Explorer 11 y cómo solucionarlos

BrowserDetectionCon la reciente Preview de la siguiente versión de Windows 8 (Windows 8.1) se ha incluido también un avance de la próxima versión del navegador de Microsoft, Internet Explorer 11.

Con IE11 Microsoft está cada vez más cerca de conseguir el nivel de compatibilidad con los estándares de la W3C (HTML5 y CSS3) que tienen otros navegadores de la competencia.

De hecho, parece que quieren parecerse tanto a los competidores que han hecho más difícil el poder identificar al navegador, por lo que mucho código viejo puede que llegue a confundirse.

Generalmente se utilizan dos técnicas para distinguir al navegador actual, dependiendo de si lo estamos haciendo en el lado servidor o en el lado cliente.

Detección en el lado servidor

En el lado servidor se utiliza la Cadena de Agente de Usuario (UAS), que es una cadena de texto que todos los navegadores envían al servidor con cada petición y que los identifica de manera única.

Por ejemplo, esta es la cadena de agente de usuario que envía Internet Explorer 10 en un sistema con Windows 7 de 64 bits:

5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; MS-RTC LM 8)

Fíjate en lo fácil que es distinguir que el navegador es Internet Explorer: lo dice directamente con la palabra “MSIE” (Microsoft Internet Explorer) y además añade la versión a continuación. Podemos ver también que es Windows 7 porque nos dice que es “Windows NT 6.1” que es la versión real del sistema operativo. Finalmente, otra buena pista, es que incluye la palabra “Trident” seguida del número de versión. Trident es el motor de renderizado de IE, como ya he explicado en otras ocasiones en este blog.

Si utilizamos Internet Explorer 11 desde Windows 8.1, las cadenas de agente de usuario que devuelve ahora son estas:

5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko - Escritorio
5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko - Versión “Modern”

5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; .NET4.0E; .NET4.0C; Touch; rv:11.0) like Gecko - Escritorio en equipo táctil
5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; Touch; rv:11.0) like Gecko - Versión “Modern” en equipo táctil

¿Por qué es importante esto?

Pues porque, hasta la fecha, todas las versiones de Internet Explorer incluían la palabra “MSIE” en su agente de usuario. Por ello, la mayor parte de las funciones de lado servidor para detectar a IE buscan dicha cadena, seguida del número de versión. Si tienes una de esas funciones en algunas de tus aplicaciones, ya puedes empezar a cambiarla. No hay más “MSIE” en la cadena de agente de usuario, así que hay que utilizar otro criterio.

Por ejemplo, un buen candidato sería localizar la cadena “Trident/” que sigue apareciendo y que indica que se usa el motor de renderizado de IE, lo cual debería ser suficiente. Podemos localizar la versión exacta del navegador bien a partir de la  versión de Trident (al final lo que nos importa es cómo se renderizan las páginas, y eso depende del motor de renderizado), o bien localizar la cadena “rv: dd\.dd”)  para ver el número de versión del navegador.

Lo malo de esta manera de localizar el navegador, es que la cadena “Trident” sólo se incluye a partir de Internet Explorer 9. Así que no llega con eso si queremos localizar versiones más antiguas. Por lo tanto el sistema debe utilizar una doble detección: si contiene las cadenas “MSIE” o “Trident” entonces es Internet Explorer.

Por cierto, fíjate que puedes detectar si el navegador se está usando en un sistema de pantalla táctil buscando la cadena “Touch” (que he resaltado en rojo), lo cual puede ser útil para mostrar interfaces más apropiadas para manejar con el dedo.

Otro detalle importante es la inclusión de la frase “like Gecko” al final. Es sorprendente que la hayan puesto, ya que Gecko es el nombre del motor de render original de Netscape/Mozilla, es decir, es el motor de Firefox, y el primero en poner eso en su UAS fue Chrome para indicar que es compatible con Gecko.

Si observamos la cadena de agente de usuario de Firefox:

Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0

vemos que lleva el motor “Gecko” indicado, y de hecho se parece mucho a la nueva cadena de IE11.

La UAS de Chrome también lo lleva:

Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36

En realidad la de Chrome refleja una personalidad múltiple, porque incluye también Safari y KHTML (el motor de KDE en el que se basa Webkit). Es más, la versión 28 que se ve en este UAS en realidad ya utiliza el nuevo motor Blink, y no Webkit, pero no ha cambiado el UAS respecto a versiones anteriores (sólo el número de versión).

Parece que, para acabar de liar las cosas más, todos los navegadores hoy en día quieren tener personalidad múltiple, y cada vez complican más el detectarlos por su cadena de usuario. Si quieres conocer un poco la historia que hay detrás de la evolución de las cadenas de agente de usuario y porqué están tan liadas hoy en día, te recomiendo que leas este artículo que lo explica muy bien.

Detección en el lado cliente

Lo cierto es que raramente deberías realizar una detección de navegador y versión en el lado cliente. El motivo es que, dada la amplia variedad de características que contemplan los navegadores en la actualidad, la disparidad de soportes que hay para las mismas en cada uno, y la velocidad con la que se lanzan nuevas versiones, lo natural no es detectar un navegador y una versión sino realizar comprobaciones de características concretas.

De todos modos, una de las maneras más habituales de determinar si nos encontramos ante Internet Explorer es verificar si existe la colección document.all, algo así:

   1: if (document.all) {
   2:     //Es IE
   3: } else {
   4:     //No es IE
   5: }

Esta colección se introdujo hace muchos años en versiones viejas de IE (creo que en la versión 4, en el año ‘97, sino me equivoco) como una manera de acceder a cualquier elemento de la página mediante JavaScript. Eso fue antes de la existencia de los métodos estándar getElementById y similares. Desde entonces lo ha venido soportando por compatibilidad hacia atrás, y por lo tanto era una buena manera de ver si el navegador actual era Internet Explorer o no.

En IE11 han hecho un cambio en el soporte de esta característica: la siguen soportando y el código que use document.all funcionará, pero la comprobación en un condicional devolverá false, así que el if del código anterior no servirá y siempre devolverá false.. Es un primer paso para dejar de utilizar estas estructuras obsoletas :-)

Conclusión

En el lado servidor deberás cambiar la lógica de detección de las cadenas de usuario para buscar la palabra “Trident” además de “MSIE”. De todos modos deberías tratar de evitarlo en la medida de lo posible y generar código HTML,CSS y JavaScript lo más estándar posible y usar detección de soporte de características en el lado cliente.

Y por eso, en el lado cliente, no detectes el navegador o su versión concreta (es mala idea) sino que deberás hacer detección individual de características concretas. Más allá de que IE11 haya cambiado algunas cosas como la detección de document.all, se trata de una buena práctica que en cualquier caso ya deberías estar siguiendo.

¡Espero que te sea útil!

José Manuel Alarcón José Manuel Alarcón
Fundador de campusMVP.es, el proyecto de referencia en formación on-line para programadores en lengua española. Autor de varios libros y cientos de artículos. Galardonado como MVP de Microsoft desde 2004. Gallego de Vigo, amante de la ciencia y la tecnología, la música y la lectura. Ayudando a la gente en Internet desde 1996.
Descarga GRATIS mi último libro (no técnico): "Tres Monos, Diez Minutos".
Banner

Comentarios (3) -

Sobre la conclusión "no detectes el navegador o su versión concreta (es mala idea)", idea también aportada por la propia Microsoft, cabe destacar que en ocasiones es necesario detectar el navegador utilizado en el lado del cliente, por ejemplo a la hora de saber si Java esta disponible en el navegador puesto que la implementación depende de la plataforma.

Dicho esto, es bueno que microsoft comience a seguir en mayor medida los estandares

Responder

Spain José Manuel Alarcón

Hola,

gracias por comentar.

Respecto a lo que dices, no es que esto lo proponga o promueva Microsoft, sino que es la manera en la que se han venido haciendo las cosas desde hace más de un década, y no tiene nada que ver en mi opinión con respetar o no los estándares. Es algo de puro sentido común. Por otro lado Microsoft lleva tratando de respetar los estándares muchos años, otra cosa es la mala fama que tengan de sus años "chungos" (sobre esto he escrito aquí):
www.jasoft.org/.../...e-es-la-nueva-Microsoft.aspx

Respecto a lo de detectar Java: no tiene nada que ver el navegador que uses con detectar Java. Java es una tecnología independiente que se instala de manera independiente a los navegadores y por lo tanto no te sirve de nada detectar el navegador concreto para averiguar si tienes Java disponible o no. De hecho la propia Sun/Oracle dispone de unas utilidades JavaScript dentro de su SDK que sirven para hacer la detección directamente desde JavaScript:

docs.oracle.com/.../deployment_advice.html

Saludos!

Responder

Me resulta muy curiosas frase como

Con IE11 Microsoft está cada vez más cerca de conseguir el nivel de compatibilidad con los estándares de la W3C

Microsoft lleva tratando de respetar los estándares muchos años

Pienso que los estandares o los sigues o no. Eso de estar cerca o tratar sólo lo veo como chapuza o directamente mala fé.

Teniendo en cuenta los esfuerzos de MS por ocultarse, me inclino más por la segunda, que además concuerda más con su trayectoría.

Es muy significativo lo del document.all, existe pero si preguntas te dice te que no.



Responder

Agregar comentario