L’histoire des User-Agents
Dimanche 10 mars 2013
C’est marrant quand on veut fabriquer quelque chose sur un sujet, on en apprend énormément sur le sujet lui-même. C’est un peu comme l’architecte qui doit non seulement être bon en math mais aussi en histoire, en géographie…Par exemple, je veux faire un petit outil qui affiche à l’écran le nom et la version du navigateur et de l’OS du visiteur à partir de l’user-agent. Très simple pensais-je… Bah non !
L’user-agent, c’est une donnée qu’un navigateur envoie au site qu’il visite et contenant des informations comme son nom et sa version.
Par exemple, Firefox 19 sous Linux envoie ça :
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:19.0) Gecko/20100101 Firefox/19.0Internet Explorer 8 sous Windows XP envoie ça :
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
Là où ça commence à être marrant c’est quand on regarde l’histoire de ces user-agent (UA): le premier navigateur graphique au monde (NCSA Mozaic, il y a plus de 20 ans) affichait ça (en sa version 2.0 sous Windows 3.1) :
NCSA_Mosaic/2.0 (Windows 3.1)Puis vint Mozilla (Netscape en fait) pour le concurrencer :
Mozilla/1.0 (Win3.1)
C’était cool non : une information simple, uniforme et facile à lire.
Mais alors… Comment en est-on arrivé à des choses compliquées comme les UA de Firefox ou IE ?
Cette page, History of the browser user-agent string, écrite par Aaron Andersen explique de façon humoristique ce qui s’est passé : je me permet une traduction libre ici.
Au commencement (1992) il y avait le navigateur NCSA Mosaic. Mosaic s’identifiait comme NCSA_Mosaic/2.0 (Windows 3.1). Il affichait les images en plus du texte et tout le monde était très heureux.
Peu de temps après arriva un nouveau navigateur appelé « Mozilla », raccourcissement de « Mosaic Killer ». Mais Mosaic n’était pas du tout amusé et Mozilla a dû changer de nom pour « Netscape », et Netscape s’identifia comme Mozilla/1.0 (Win3.1) et tout le monde était à nouveau très heureux.
Mais Netscape supportait l’affichage de frames (cadres HTML), et les frames devinrent très populaire, mais Mosaic ne supportait pas les frames et donc naquit la pratique de la détection de l’user-agent, et les sites web envoyaient les frames à Mozilla et ne les envoyaient pas aux autres.
Et Netscape se dit « moquons nous un peu de Microsoft et faisons référence à Windows comme un "pilote pour matériel mal débuggé" ». Microsoft était furieux, et Microsoft conçu son propre navigateur qu’ils appelèrent Internet Explorer, en espérant qu’il deviendrait un « Netscape Killer ». Internet Explorer supportait les frames, mais il n’était pas Mozilla donc les sites ne lui donnait pas les frames.
Microsoft s’impatienta et ne voulu pas attendre que les webmasters mettent à jour leur site et du coup Internet Explorer, étant en fin de compte « compatible Mozilla », se fit passer pour Mozilla et s’identifia comme Mozilla/1.22 (compatible; MSIE 2.0; Windows 95), et Internet Explorer recevait bien les frames, et Microsoft était content, mais les webmasters assez confus.
Et Microsoft vendit IE avec Windows, et le rendit mieux que Netscape, et ce fut la guerre pour qui avait le meilleur navigateur. Et finalement, Netscape mourut et Microsoft était vraiment très heureux.
Mais Netscape ressuscita en tant que Mozilla, et Mozilla construit Gecko, et Mozilla s’identifia comme Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.1) Gecko/20020826 et Gecko était le moteur de rendu des pages, et Gecko était bon. Mozilla devint finalement Firefox et se nomma Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.7.5) Gecko/20041108 Firefox/1.0 et Firefox était très bon. Et Gecko était repris par d’autres navigateurs qui se nommèrent par exemple Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.2) Gecko/20040825 Camino/0.8.1 pour l’un ou Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.8) Gecko/20071008 SeaMonkey/1.0 l’autre. Et chacun d’eux prétendaient être compatibles Mozilla et tous tournaient sur Gecko.
Et Gecko était bon, et IE ne l’était pas et la détection de l’user-agent renaissait, et Gecko recevait le bon code et les autres navigateurs ne le recevaient pas. Mais les utilisateurs de Linux étaient bien tristes car ils avaient construit Konqueror, dont le moteur de rendu était KHTML, et qu’ils pensaient être aussi bon que Gecko mais n’était pas Gecko, et ne recevait donc pas les bonnes pages.
Konqueror déclara être « comme Gecko » puis pour avoir les bonnes pages, il s’identifia comme Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD) (KHTML, like Gecko) et il y avait beaucoup de confusion…
Puis Opera déclara « nous devrions laisser le choix à l’utilisateur concernant le navigateurs dont il doit prendre le nom ! » et Opera créa un menu de choix et Opera s’identifia comme Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.51 ou Mozilla/5.0 (Windows NT 6.0; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.51 ou Opera/9.51 (Windows NT 5.1; U; en) selon le choix fait par l’utilisateur.
C’est alors qu’Apple construit Safari, et repris KHTML en ajoutant plein de bonnes choses, et repris finalement le projet tout entier et l’appela WebKit, mais voulurent quand même les pages écrites pour KHTML, et donc Safari se nommait Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5 et la confusion était encore plus grande.
Entre temps Microsoft avait très peur de Firefox et Internet Explorer revint devant et se nommait alors Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) et il affichait le bon code… Mais seulement si les Webmasters le décidaient…
Et enfin Google construit Chrome, et Chrome utilisait WebKit et il était comme Safari et voulait les pages destinées à Safari et donc s’identifia comme Safari. Donc Chrome utilisait Webkit, en prétendant être Safari, et WebKit prétendait être KHTML, ce dernier s’affichait être comme Gecko et tous les navigateurs se faisaient passer pour Mozilla… Chrome se nomma Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13 et l’user-agent était devenu une gros foutoir pratiquement inutile, et tout le monde prétendait être tous les autres et la confusion était à son comble…
Voilà un peu l’histoire de quelque chose de simple devenant un véritable bordel impossible à gérer, et tout ça parce que d’un côté les navigateurs ne sont pas tous égaux et supportaient leurs propres série de fonctionnalités non standards, de l’autre les webmaster qui voulaient utiliser des choses proposés par un navigateur en particulier et entre les deux l’utilisateur qui la plupart du temps prenait le plus pourri des navigateurs…
Moi ça me fait bien rire, parce que c’est assez marrant mais aussi parce que c’est quand même assez vrai que certaines choses deviennent de plus en plus compliqués à cause de patchs et de reprises dans tous les sens.
Malheureusement ceci pose également beaucoup de problèmes : les sites qui ont encore des systèmes de détection du navigateur sont nombreux et continuent d’être créés. C’est mal : cette détection peut souvent être foireuse et elle oblige le webmaster à construire plusieurs version de son site, alors qu’une seule version pourrait suffire si le webmaster savait coder proprement et si le site web ne se devait pas d’avoir toutes les options dernier cri.
Je pense que cette histoire va m’aider pour construire quelque chose pour détecter les user-agents : il suffit finalement de faire un arbre et on voit comment optimiser le traitement des opérations. Et les moteurs de rendu sont en nombre limités, donc ça devrait aller. Du moins pour les grands navigateurs sur desktop, parce que après il y a encore Nokia, et tous les autres qui ont les leurs.
Oh, et Opera Mobile utilisera WebKit dans le futur. La version beta est déjà sortie sur Android. Voici son user-agent, juste pour rire :
Mozilla/5.0 (Linux; Android 2.3.6; YP-G1 Build/GINGERBREAD) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.123 Mobile Safari/537.22 OPR/14.0.1025.52315
MAJ du 27/03/13 : et ça continue : IE 11 pourra s’identifier comme Firefox avec un « like Gecko » ajouté à son user-agent. C’est magnifique.
Le Hollandais Volant
BUPO : #
Moi je propose : Navigateur/Version Moteur/Version MoteurJS/Blabla ; [TextMode](HTML/Norme.Date CSS/Norme.Date JS/Version [Ajoutez les autres choses standards au même format]; compatible; Flash/Version [Et tout le reste comme on veux, plugins]) [OS]
!
Donc pour Opera(Admettons les imperfections) Opera/12.14 Presto/2.12 Carakan/ ; (HTML/5.AAAA-MM-JJ CSS/3.AAAA-MM-JJ JS/2.0 ; compatible; Flash/11,2,202,261 ) X11; Linux i686
C'est bien plus simple, je ne suis pas pro donc il DOIT manquer quelque chose. Après il faudrait compléter pour l'OS.
J'explique mon choix :
Le début avant parenthèse, c'est le navigateur, QUE LE NAVIGATEUR.
On peut ajouter si le navigateur est textuel après un point virgule car c'est important. Ensuite on passe à la parenthèse, donc les détails. On définit es standards supportées, qui est le plus important pour un développeur et qui évite de connaître tous les standards par coeur. Pour les détails il y a les infos du navigateur. Le format de la date est définit pas l'ISO. ENSUITE, un point virgule car c'est plus rien à voir. On retrouve le "compatible ;", pour passer à ce qui n'est pas obligatoire. Je pense qu'on pourrait séparer par des ; les "différentes catégories" ( Plugins, Modules?,... ). Au final, on laisse la place à l'OS et en réalité, tout l'environement logiciel qui est important mais pas crucial.
Cela s'applique pours les navigateurs normaux, pour les bots on pourrait imaginer autre chose.
d'autres exemples:
IE10 : MSIE/10.0.9200.16384 Trident/6.0 Chakra/
(HTML/5.AAAA-MM-JJ CSS/3.AAAA-MM-JJ JS/2.0 ;compatible; ) WindowsNT/6.2 ; WOW64 ; Win8/
Firefox 19 : Firefox/19.0.2 Gecko/9.0 IonMonkey/ (HTML/5.AAAA-DD-JJ CSS/3.AAAA-DD-JJ JS/2.0 ;compatible; ) WindowsNT/6.2 ; WOW64 ; Win8/
Voilà la démonstration est terminée !
PS : En réalitée On pourrait préciser si la version utilisé est en Beta/Alpha/Whatever. Par ex: Opera(Beta)13.10 et créer des attributs universels pour voir quel type d'appareil. Après les parenthèse on pourrait voir "Touch" pour noter la présence d'écran tactile. et "Mobile" "Tablet" "Smatphone".
BUPO : #
En fait c'est
Le Hollandais Volant : #
@BUPO : ou aucun UA, forçant les webmasters à faire tes sites compatibles :p.
Ou alors faut que les utilisateurs d’IE6 et Firefox -12 assument de ne pas avoir un navigateur à jour…
BUPO : #
T'as niqué toute ma théorie to/
Julien et Nel : #
Pour ma part, j'essaye de coder pour les standards actuels et je me fous de savoir si ça va marcher sur le reste.
Les utilisateurs n'ont qu'a mettre à jour leurs navigateurs et à en utiliser un qui respecte les standards.
Allchimik : #
@Julien et Nel : +1 si c'est à jour ça passe bien généralement
kinezana : #
Et au final tu as trouvé une solution pour "faire un petit outil qui affiche à l’écran le nom et la version du navigateur et de l’OS du visiteur à partir de l’user-agent" ?
Le Hollandais Volant : #
@BUPO : U MAD BRO ?
@Julien et Nel : idem :). Sauf les CSS3 : je les ajoute tous (-webkit-, -moz-, etc.).
@kinezana : je suis en train de le coder là. En quelques lignes bardé de preg_match() j’ai déjà le traitement pour Opera et MSIE (j’ai même ajouté le gestion de la détection du mode de compatibilité pour IE.
Lentement mais sûrement :).
Si je veux faire tous les navigateurs, je devrais avoir fini d’ici 2032.
iTux : #
Est-il possible de changer l'UA envoyé aux sites ?
Question valable pour les logiciels libres, et si ça ne vous embete pas, pour Chrome (le commercial, pas Chromium) et Safari.
Le Hollandais Volant : #
@iTux : cest possible, oui : dans Firefox et Opera il est possible de donner nimporte quoi comme UA.
Pour les autres, je ne sais pas, mais certains modules le font facilement.
Guenhwyvar : #
Là, le premier truc auquel je pense, c'est : pourquoi faire ?
@iTux : Pour Firefox, y'a au moins ça : https://addons.mozilla.org/fr/firefox/addon/user-agent-switcher/
Erik : #
Pour Opera, l'histoire remonte à très longtemps avant sa version 9. Il permettait déjà de falsifier son user-agent quand je l'utilisais en 2000... à l'époque, Opera était payant ou bien dispo en version gratuite contre affichage de pubs dans le navigateur.
Julien et Nel : #
On peut aussi changer le referer : Ça évite de se faire pister et on fait sa pub comme ça ...
Le Hollandais Volant : #
@Guenhwyvar : pourquoi pas ?
Fox : #
Sinon, utilise UA-Parser.JS (7.611 kb pour sa version minifiée), c'est ce que j'utilise pour une des pages de ma liste d'outils de dev' en ligne. Au fait, tu m'autorises à y rajouter ton outil de calcul de dates ? :)
Julien et Nel : #
En ce qui concerne l'user agent, je n'aime pas vraiment être pisté non plus .
Pour le referer, j'ai utilisé l'adresse pour télécharger mon script ;) .
Pour l'user agent, ça retourne le nom du script comme nom de navigateur .
Où comment troller gentiment la personne qui chercherait à collecter mes données .
Le Hollandais Volant : #
@Fox : J’ai déjà trouvé UA-Parser, mais c’est trop lourd en JS (y’a toute la lib JQuery à télécharger en plus.
Je préfère construire un truc tout neuf :-)
Pour les dates, bien sûr ! Sauf qu’on m’a reporté un petit bug : essayes en calculant la différence entre deux dates où tout est identique sauf les années. Je pense que ça vient du Date() dans JS lui même : ce qu’il fait c’est que pour lui "hier" c’est pareil que –1an + 11mois + 31jours.
Un peu con, mais si tu trouves une solution ou la source du problème, je suis preneur (via Email :)).
Fox : #
@Le Hollandais Volant : Nop', UA-Parser est compatible jQuery, mais il peut fonctionner sans. D'où la fonction de vérification de la présence de jQuery à la fin de la librairie. :) En tout cas c'est sûr que re-faire soi-même permet d'apprendre beaucoup.
Je regarderai pour le bug des dates si j'ai quelques minutes. Quand je le rajouterai à ma liste d'outils un lien "sources" sera évidemment bien visible.
baba : #
UA-Parser : 7Ko compressé juste pour ça ? C'est une blague ?
J'utilise ce code : http://www.quirksmode.org/js/detect.html
2 ko non compressé, le code est propre, il fonctionne partout, pas besoin de lib jquery et cie (ce qui, entre nous, devrait être une norme !).
Ca me fait penser à ça :
http://www.doxdesk.com/img/updates/20091116-so-large.gif
http://forum.jquery.com/topic/basic-addition
Le Hollandais Volant : #
@baba : Excellent ton code JS !
Le JS permet de détecter les objets comme opera.document() ou autres, j’avais zapé ! IE et les commentaires conditionnels permettent ça aussi, sûrement !
Mon but est de faire une page SIMPLE comme ça : http://supportdetails.com/
Ton code est parfait pour faire de la détection de navigateur et lancer un script adapté. Mais pour afficher le nom du navigateur à l’écran c’est un peu plus dur.
Par exemple, pour tester j’ai installé plein de navigateurs sur une machine virtuelle.
Ton code affiche par exemple "Chrome" à la place de Iron, Chromium, CoolNovo, RockMelt. En pratique ce n’est pas grave (ces navigateurs sont tous basés sur chrome), mais pour ce que je veux ça ne suffit pas.
Pour l’instant j’arrive à faire quelques trucs sympas en PHP et j’en suis à 6ko (documenté), il m’en faudrait le double je pense.
UA-Parser a l’avantage d’avoir un grand nombre de noms dans sa BDD, par exemple pour Camino, SeaMonkey, Konqueror et aussi des navigateurs mobiles, de Nintendo, Symbian…
iTux : #
@Le Hollandais Volant : Iron, Chrome, CoolNovo et RockMelt sont basés sur Chromium, pas l'inverse.
Le Hollandais Volant : #
@Le Hollandais Volant : PS : UA-Parser ne fait pas mieux concernant tous les aliages de Chrome (oui, j’appelle ça des alliages^^) que sont Iron, CoolNovo et compagnie.
Il affiche tout simplement Chrome.
Mon truc se base sur un dictionnaire concernant les moteurs de rendu et sur les regex pour détecter tout le reste.
Si un navigateur est basé sur Firefox par exemple, il trouvera son nom même si elle n’est pas dans la BDD.
Guenhwyvar : #
@Le Hollandais Volant :
Rien ne vaut le Vanilla.
Spin0us : #
Perso j'utilise browscap.ini (http://tempdownloads.browserscap.com/) pour la détection des UA. Mais c'est uniquement à titre informatif pour le visiteur, et accessoirement pour quelques statistiques.
K13b3r : #
Super article, je me suis déjà demandé pourquoi les noms étaient pas plus simples, mais jamais eu letemps de vraiment chercher.
Donc merci.
Et merci pour blogotext, en cours de restylage du css pour une utilisation bientôt.
L'Oiseau Geek : #
Merci pour cette traduction et l'historique complet qui va avec; comme souvent en informatique, cela permet de comprendre comment on est arrivé à une situation aussi aberrante au niveau des User-Agents.
Dans le principe, il faudrait bien entendu détecter les fonctionnalités des navigateurs plutôt que le "modèle". Si cela avait été fait à l'origine avec des chaines du type "Frame, Cookie, HTML4, ... Compatbile" ce serait déjà plus propre.
Maintenant, avec le nombre de fonctionnalités et plugins existant on ne s'en sortirait pas et les requêtes HTTP seraient 3 fois plus lourdes.
Pour la détection du support des fonctionnalités HTML5 / CSS3 il y a Modernizr: http://modernizr.com/.
Pour info, Chrome permet nativement de modifier son User-Agents en ouvrant le volet "developpeur" en bas et en cliquant sur son icone de réglage en bas à droite, il y a une section Overrides dans laquelle une liste de UA est proposée, sinon on peut en saisir un manuellement c'est assez amusant à tester sur certains sites.
Alain Ternaute : #
C'était voulu, cette ressemblance avec le texte de la Génèse ? lol
Le Hollandais Volant : #
@Alain Ternaute : possible, j’ai repris le style de l’article d’origine^^.
Janus24 : #
www.pcinpact.com/news/78509-internet-explorer-11-peut-sidentifier-comme-firefox-pour-eviter-hacks-css.htm
C'est pas encore fini le bordel avec les User-Agents ...