Aller au contenu

Les User Agents, c'est le mal !

Par Rudy Rigot

Mini-conf (15 mn) :
Langue :
Français
CC

Le sujet

Savez-vous pourquoi depuis sa première version, Microsoft Internet Explorer se fait passer pour Mozilla aux yeux des serveurs web ?

Et savez-vous aussi pourquoi Opera tente désespérément de cacher à ces mêmes serveurs web qu’ils ont un jour sorti une version “10” ?

Il ne manque pas d’exemples de FAILs historiques dûs à ce petit espiègle qu’est le “User Agent”, entête HTTP destiné à laisser le navigateur se présenter comme il l’entend, mais en version bien souvent un peu mythomane sur les bords !

Et puisque montrer du doigt, c’est mal, alors que présenter des solutions, c’est mieux, nous verrons aussi ensemble les tentatives qui sont expérimentées aujourd’hui pour mieux maîtriser le rendu web, mais du côté du client, et en quoi ça va pragmatiquement être plus propre.

Présenté par

Transcription

(Transcription par Tanguy Lohéac et Sophie Schuermans. Merci à eux)

[Applaudissements]

Rudy Rigot : Eh ben, bonjour tout le monde. Bienvenue à Paris Web. J’espère que vous vous éclatez bien tous.

Vous m’entendez ou pas ?
Ouais. Je sais qu’il est 12h30. Donc je sais qu’il se fait faim. Il se fait faim pour moi aussi. Donc on est tous ensemble dans le même bateau.

Du coup ce que je vous propose pour nos 15 dernières minutes de la matinée, c’est qu’on parle de quelque chose, d’un peu… qui soit pas un sujet particulièrement de fond. C’est quelque chose d’assez léger, d’assez rigolo : les user agents c’est quelque chose de fun, c’est l’éclate ! Et surtout mon objectif dans tout ça c’est d’essayer de faire en sorte qu’en sortant de cette pièce vous disiez plus juste : « sniffer du user agent c’est mal ! », vous disiez : « sniffer du user agent c’est mal, et je sais pourquoi ! Et des fois hé ben on est obligé. Et je sais pourquoi aussi ! ». Voilà ! Donc on va essayer de faire ça tous ensemble.

Alors déjà je parle un petit peu de moi. Mais je le fais vraiment en accéléré. Je suis entré chez Clever Age, je travaille chez Clever Age dans le dev. J2E à la base, personne n’est parfait. Et du coup, j’ai continué dans plein d’autres trucs, jusqu’à arriver à de la gestion de Business Units. Et du coup, ce qui me fait arriver aujourd’hui à un projet assez intéressant en 2013 : c’est moi qui vais porter le projet Clever Age New-York ! Donc du coup ça devrait être super sympa ! [Quelques sifflets et applaudissements d’admiration dans la salle] Suivez-moi sur Twitter, je vais avoir plein de trucs à raconter !

Autre truc intéressant sur moi : en ce moment je suis en train de coécrire un livre avec Jérémie Patonnier (qui est juste au premier rang) qui parle de conduite et de conception de gestion de projet « responsive » qui devrait sortir en 2013 aux Editions Eyrolles. Donc restez connectés aussi. Et du coup, ben passons à autre chose ! Parlons du sujet : User agents !

Alors, les user agents, oui c’est le mal. Mais déjà à quoi ça sert ? Faisons un petit rappel en disant pourquoi les user agents est-ce que ça peut être utile. Ben l’utilité première c’est de partir de l’idée que aujourd’hui, sur le marché, de tous les navigateurs, il y a énormément de plateformes différentes, que ce soit au niveau du navigateur en lui-même, ou du device, ou de l’OS etc etc… Quand ces navigateurs-là font un appel HTTP, ils envoient des requêtes. Ces requêtes sont accompagnées de headers HTTP. Je reste très basique, hein dans ce que je dis. Ces headers HTPP, c’est plein de trucs. Il y a des paramètres de l’URL, enfin des paramètres de requête, il y a la langue du navigateur, enfin beaucoup de choses sur le contexte initial du navigateur. Ça traverse le web. Ça arrive dans le serveur. Et le serveur reçoit ça. Il reçoit cette requête et il se dit : « ben mince ! Si seulement j’avais un header HTTP propre à chaque navigateur pour pouvoir différencier entre chacun et renvoyer à chacun le truc idéal pour chaque contexte !

C’est magique ! Le user agent est là pour ça ! C’est cool ! Et pour le coup, dans sa mission d’avoir un user agent unique par navigateur, ça il le fait bien. Il y en a bien en effet un unique par navigateur. Donc, what is the fuck ? Quel est le problème ? Plus ou moins [rires].

Parlons de ce qui s’est passé au niveau du user agent dans l’histoire et qui fait qu’aujourd’hui on se dit : « mais non, c’est une très bonne idée peut-être à la base, mais ça devient n’importe quoi aujourd’hui ! »

Faut se rappeler qu’à la base il y avait un navigateur graphique. Ce navigateur il s’appelait Mosaic. Il a été créé par NCSA qui est une division de l’armée américaine. Et le premier user agent était plutôt logique : NCSA Mosaic slash le numéro de version entre parenthèse l’OS [NCSA_Mosaic/2.0 (Windows 3.1)]. Plutôt cool ! Bien vu ! Puis est sorti Mozilla. Enfin le projet Mozilla qui s’appelait Netscape à sa sortie et qui a eu un user agent aussi, qui a continué un peu la tradition du logique : Mozilla slash version (O.S) [Mozilla/1.0 (Win3.1)]. Puis, (je saute plus ou moins des projets et des étapes mais…) puis est sorti… La question s’est posée, du moins pour le développeur de : « mais attendez ! J’ai un navigateur ici qui fait plein de trucs super cools avec des technologies modernes, d’avenir comme les frames ! [Rires dans la salle] Et il faut que je puisse savoir si j’envoie ma page avec des frames, ou une page qui n’a pas de frame pour que Mosaic qui est un peu plus limité en ce moment puisse les reconnaître ? » Super ! J’ai le user agent ! Donc, je vais attraper le user agent. Je vais regarder s’il y a Mozilla d’écrit dedans. Et puis, s’il y a Mozilla d’écrit dedans, je vais envoyer une version hypra-moderne framée. Et s’il n’y a pas, ben du coup j’enverrais ma version vieille. Sauf que… au navigateur suivant qui a essayé d’arriver, avec son user agent plutôt logique, le problème s’est posé [MSIE/2.0 (Windows 95)]. « Ah ouais mais si j’essaie d’arriver avec ce user agent, je vais être détecté comme un vieux navigateur pourave. Sauf que moi j’essaie d’avoir des fonctionnalités super-modernes comme l’autre. Donc du coup qu’est-ce que je fais ? Eh ben je vais un peu mentir » [Mozilla/1.22 (compatible; MSIE 2.0; Windows 95]. Voilà ! Je suis Internet Explorer 2 et puis ben je dis que je suis Mozilla, mais compatible. Et puis, en fait, je suis Internet Explorer qui fait semblant d’être Mozilla. Plus ou moins. C’est là que le bordel a commencé. À la suite de ça, il y a eu une refonte de Netscape et de toute la codebase de Netscape 4. Ce qui a donné du coup Netscape 6 après ça [Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.1) Gecko/20020826]. Ce qui a donné naissance aussi au fait que le moteur de rendu web a été séparé. Il s’appelle Gecko. Il est publié en open source et il est utilisé par d’autres navigateurs, dont les navigateurs suivants. Enfin il y en a plein d’autres. J’imagine. En tout cas j’les connais pas. Mais au moins Firefox, Camino, SeaMonkey qui peuvent utiliser librement Gecko.

Du coup, on obtient des navigateurs qui font semblant d’être Gecko, même s’ils le font partiellement, pour être sûr d’obtenir… d’être matchés comme étant Gecko et avoir les pages qui reconnaissent Gecko, lequel fait semblant d’être Mozilla. D’accord. OK. Ça commence à devenir what is the fuck très fort quoi. À la suite de ça ben la question s’est à nouveau posée : « Ah oui mais attendez ! Internet Explorer il a un petit retard aussi par rapport aux navigateurs Gecko. Alors moi, développeur, je fais comment pour savoir quelle version de ma page j’envoie ? » Et pour répondre à ça, c’est plutôt du côté navigateur qu’il y a eu une réponse qui est arrivée, sous forme de parenthèses et d’épisodes, qui a été Opera ; qui a une période s’est dit : « on arrête les conneries » (c’est un petit peu coupé tant pis [il parle de sa présentation]). On arrête les conneries ! Moi je reprends mon user agent classique [Opera/9.51 (Windows NT 5.1; U; en)]. Parce que bon, ça suffit. Par contre, j’offre deux modes de compatibilité : un mode Gecko et un mode IE. Comme ça, l’utilisateur ben il décide, je veux voir le site qui est prévu pour Gecko, je veux voir le site qui est prévu pour IE. Voilà ! Ça simplifie tout. Évidemment, maintenant tout est clairement très très simple.

Bon, je ferme cette parenthèse historique.

À partir de Gecko se sont créées beaucoup d’autres initiatives, notamment Apple qui a créé Apple Webkit qui est d’autant plus bien connu aujourd’hui, qui était issu d’un projet open source qui s’appelait KHTML. Du coup on a Apple Webkit qui fait semblant d’être KHTML pour être sûr d’être reconnu comme étant KHTML, mais qui fait aussi semblant d’être Gecko, lequel fait semblant d’être Mozilla. Ce qui donne donc naissance à Safari [rires dans la salle] qui fait semblant d’être Apple Webkit qui fait semblant d’être Gecko et KHTML qui fait semblant d’être Mozilla. [Quelques rires dans la salle]

Tout va bien ! Tout va bien !

Et, évidemment, à la suite de ça il faut que les navigateurs qui suivent, suivent la mouvance. [Dit en accéléré] : et du coup vous avez Chrome qui fait semblant d’être Safari qui fait semblant d’être Apple WebKit qui fait semblant d’être Gecko et d’être KHTML lequel fait semblant d’être Mozilla.
Donc les user agents c’est super simple finalement ! Donc voilà ! Non il y a un vrai problème avec les user agents qui est dans l’historique de ce qui s’est passé avec. Ce qui fait qu’aujourd’hui vous avez des navigateurs qui n’ont pas d’autre choix que de mentir, entre guillemets.

Aujourd’hui vous avez une autre problématique qui se pose. C’est la problématique moderne des user agents que vous avez peut-être vue en projet. Qui est de se dire : « mais attendez, moi tous ces navigateurs-là, il faut que je puisse les différencier d’avec les navigateurs mobiles ! »

Là, en ce moment c’est un peu le truc. C’est : je suis un client, je veux un site desktop oui, mais je veux aussi un site mobile. Et je veux qu’on détecte. Et je veux qu’on passe sur l’un, sur l’autre. Comment je fais, moi en tant que développeur, pour tester tout ça ? Est-ce que je teste… Je fais sur quel mot-clé, sur Androïd, sur iOS, sur mobile pour choper tout ce qui est mobile, sur Windows Phone 7 ? Mais j’oublie pas non plus les trucs peut-être un peu plus à la marge comme Web OS, comme Palm OS, comme Pocket PC, comme le Palm Pre, comme tous ces trucs ? Eh ouais ! Si le mec il arrive avec, et ben il faut que ce soit reconnu.

Bah la réponse elle est simple. C’est : « aller, je vais pas être chiche. Je vais tous les tester. » Voilà. Je les prends tous. Je regarde. Il y a Pocket, il y a Androïd, il y a Web OS ? Tout ça c’est bon ! C’est mobile. Le reste, c’est pas mobile. C’est tellement plus simple.

Sauf que non. Parce que si vous prenez le user agent d’Opera aujourd’hui ou récemment, vous avez quelque chose qui contient le mot « pre ». Presto c’est le moteur de rendu web d’Opera. Donc là vous arrivez avec un Opera Desktop, totalement desktop. Et vous avez un site de l’autre côté qui vous reconnaît comme étant un Palm Pre, donc qui vous renvoie le site mobile. Yes ! [Quelques rires sarcastiques dans la salle]

Trop la classe ! Et, évidemment, puisque ça n’arrive jamais aux grands… C’était le cas du Département d’État des États-Unis à l’époque. [Rires amusés dans la salle]

Voilà ! Donc ça arrive vraiment. C’est pas un cas à la marge. C’est vraiment quelque chose qui pose des problèmes. Et qui est vraiment problématique.

Autre problème de user agent, d’ailleurs petite parenthèse historique encore. Opera 10 est sorti. Il est sorti en version Alpha avec un user agent, bon, logique, très logique même par rapport à ce qu’est Opera 10. Mais sauf que, ben ils ont relâché ça [Opera/10.0 (Windows NT 6.0; U; en) Presto/2.2.0]. Et que certains sites détectent, non pas pour détecter si c’est mobile ou pas, mais pour détecter la version du navigateur.
Ah c’est un Opera ! J’aimerais bien savoir quelle version, pour savoir quelle version de ma page web je lui envoie. Et il y a des sites qui du coup tombant sur Opera testent les 7 premiers caractères. C’est Opera 1 [rires dans la salle].

Voilà. Donc les user agent parsing ça marche pas. C’est du string parsing, donc c’est problématique. Et en plus vous avez des user agents qui mentent. C’était le cas d’allocine, à l’époque. Donc c’est vraiment des problèmes qui arrivent réellement. Bon ben c’est cool !

Voilà. Je vous dis les problèmes. Mais avec tout ça j’aimerais bien aussi que vous disiez : « ben ouais, du coup je fais quoi moi avec mon site ? T’es bien rigolo ! »

Ben la solution elle va se situer (on est à Paris Web donc il faut faire un peu de zèle), elle va se situer quand on arrive ici, dans le fait que le serveur, qui tout à l’heure disait : « je veux savoir quel est le user agent », dise : « je veux pas savoir quel est le user agent. La décision sera prise du côté du client ! »

C’est ça. Le pouvoir par le front-end. Vous envoyez l’intégralité du code qui peut être utile (on va simplifier), par le navigateur. Et c’est le navigateur du côté front-end qui va appliquer tout ce qui va bien, ce qui lui correspond à lui, qui va prendre la décision de ce qui lui correspond. Pour ça il existe des outils.

En CSS vous pouvez appliquer des media queries que vous connaissez bien. Mais il y a aussi des support queries qui sont pas particulièrement extraordinairement supportées partout. Mais ça avance. Ce qui permet de dire je déclenche ce bloc CSS si la géolocalisation existe sur mon navigateur, par exemple. Et en JS vous avez des possibilités d’utiliser des objets JS tout prêts pour vous pour détecter les fonctionnalités qui existent ou non pour exécuter du JS. Vous avez des outils qui existent comme Modernizer qui vous facilitent cette tâche-là.

Donc vous avez vraiment des choses qui existent qui vous permettent de faire ça par le front-end. Donc tout va bien. Et puis bon, pour les cas à la marge où vous avez vraiment besoin de séparer entre sites mobiles et sites non mobiles, par exemple, ben vous allez essayer de trouver des solutions pour contourner le truc.

Donc, ce qui se fait bien aujourd’hui, c’est de mettre un lien de chaque côté sur le site pas mobile vers le site mobile, et sur le site mobile vers le site pas mobile. Comme ça vos faux positifs que vous avez vraiment pas le choix de laisser passer, vous pouvez les récupérer. En le faisant par la conception et par le design plutôt que par la technique.

Par contre, si je vous dis : « faites tout par le front-end et vous n’aurez jamais aucun problème dans le monde. » vous allez me dire : « mais ouais mais tu m’as dit que pour les sites mobiles il n’y a pas de solution. »

Eh ben oui. Il y a des limites. Il y a des cas à la marge qui font que parfois le front-end va vous poser problème. Des fois, le front-end va vous mentir. Le front-end vous ment, travailleurs, travailleuses !

Ce qui va se passer c’est que par exemple vous allez prendre certains téléphones modernes [rires dans la salle] (je rigole. En fait il y a pas mal de Nokia smartphones, évidemment c’est pas ceux-là, qui ont le problème en question, il y a aussi les Androïd 2 quelque chose, il y a un article de Kaelig je crois qui est dans la pièce, qui est sorti il y a pas longtemps où il écrit tout ça). Et ces téléphones-là vous leur dites : « est-ce que tu supportes le font-face ? ». Il va dire : « ouais grave ! ». Alors que en fait non, pas du tout quoi ! Ils font semblant de supporter des trucs qu’ils ne supportent pas. Donc du coup si vous envoyez tout par le front-end [claquement de doigts], eh ben le front-end vous ment. Et là vous faites : « euh what is the fuck ! Encore quoi ».

Donc du coup vous vous dites, ouais le front-end me ment, soit, mais faut quand même que je remette en perspective, en toute relativité, beaucoup moins que les user agents qui depuis le début, je vous l’ai prouvé, vous prennent un peu pour des couillons. Et en plus, ça reste plus pérenne parce que c’est un code qui devrait fonctionner de manière un peu plus logique dans l’avenir, en respectant les standards qui sont faits pour fonctionner dans l’avenir. Donc ça reste logique d’essayer de passer à maximum par le front-end.

Deuxième problème : en plus le front-end se moque de vous ! Je vous assure ! Pourquoi ? Parce que par exemple, je sais pas si vous connaissez cette fonction : vous prenez un élément vidéo, et vous lui appliquez la fonction canPlayType. Et canPlayType, vous lui passez un type MIME sous forme de string, et derrière il est censé vous répondre : « oui, moi navigateur, ton élément vidéo, s’il est de tel encodage, je suis capable de le lire ou je ne suis pas capable de le lire. »

Et dans la spec de canPlayType, dans la spec hein ! C’est même pas les navigateurs là. Dans la spec il est écrit canPlayType peut répondre soit yes, soit vide qui veut dire non, soit [rires dans la salle] maybe, on va essayer, on va voir ce qui se passe, et à partir de là, je te dirai si c’est bon ou si c’est pas bon. Et puis il y en a un quatrième [nouveaux rires dans la salle] [probably]. Essaie ! Ça devrait y aller.

Voilà donc c’est un vrai problème de fond par rapport à certains éléments d’API du front-end qui vont pas vous répondre de manière claire.
Donc le front-end ne va pas tout le temps vous apporter des réponses claires. On va encore replacer ça en relativité. On va se dire qu’il se moque de vous certes, mais les user agents se moquent carrément plus de vous. Donc au final, vous vous retrouvez dans une situation qui est plus maîtrisée.

Alors du coup, qu’est-ce qu’on se dit en conclusion ? Qu’est-ce qu’on fait ? Voilà, j’ai un projet, je fais quoi ? J’en sors quoi de cette conférence ? Qu’est-ce que je fais ?
Ben je me dis, il y a un peu deux manières de faire. Soit vous partez sur l’idée que vous appliquez une solution simple, dans un budget limité ou dans un temps limité etc. Mais en mettant l’accent sur la pérennité. Et vous vous dites, je lâche prise de ce que je peux pas contrôler. Donc je fais en sorte que le site soit un maximum accessible sur un maximum de périphériques en respectant les standards. Je corrige potentiellement, via du user agent ce que vraiment j’ai pas le choix de corriger, qui doivent être des cas uniquement à la marge du front-end. Pas pour autre chose. Et je fais ça de cette manière-là.

Deuxième solution : j’ai du temps, j’ai de l’argent, j’ai de la R&D. Je fais des trucs qui vont être des server-side components. Donc en gros, mon élément vidéo, ben canPlayType je ne l’applique que quand le user agent n’est pas ça, ça, ça, ça. Parce que je sais que ceux-là ils vont me mentir. Voilà.

Ça peut être une solution d’essayer d’être perfectionniste. C’est ce que fait la BBC qui a une équipe qui est dédiée aux user agents, qui réalise l’outil de sniffing de user agent basique pour essayer de rétablir les mensonges et les erreurs du front-end. Et d’ailleurs, à ce propos-là, si vous avez des questions sur ce que fait cette équipe, sur comment ça fonctionne dans la BBC, j’ai tiré beaucoup d’informations d’un Monsieur qui s’appelle Kaelig, qui est dans la salle (je sais pas où il est). Mais n’hésitez pas, il est là. N’hésitez pas à aller le voir. Il a un pull vert. Vous le reconnaîtrez. N’hésitez pas à aller le voir après. Parce que du coup il maîtrise le sujet de comment ça s’organise chez eux. Et du coup, j’en profite pour le remercier, et pour vous remercier de m’avoir écouté. Voilà, j’espère que vous en avez tiré quelque chose.

[Applaudissements]