web-dev-qa-db-fra.com

Détection du navigateur et détection des fonctionnalités

Je vais jouer l'avocat du diable pendant un moment. Je me suis toujours demandé pourquoi la détection de navigateur (par opposition à la détection de fonctionnalités) était considérée comme une mauvaise pratique. Si je teste une certaine version de certains navigateurs et que je confirme que certaines fonctionnalités se comportent d'une manière prévisible, il semble normal de décider de le faire dans un cas particulier. Le raisonnement est qu'il sera à l'avenir infaillible, car cette version partielle du navigateur ne changera pas. En revanche, si je détecte qu'un élément DOM a une fonction X, cela ne signifie pas forcément que:

  1. Cette fonction fonctionne de la même manière dans tous les navigateurs, et
  2. Plus important encore, cela fonctionnera de la même manière, même dans tous les futurs navigateurs.

Je viens de jeter un coup d'œil dans la source jQuery et ils détectent les fonctionnalités en insérant un extrait de code HTML soigneusement construit dans le DOM, puis ils le vérifient pour certaines fonctionnalités. C'est un moyen sensé et solide, mais je dirais que ce serait un peu trop lourd si je faisais quelque chose comme ça dans mon petit morceau de JavaScript personnel (sans jQuery). Ils ont également l'avantage de ressources d'assurance qualité pratiquement infinies. D'un autre côté, ce que vous voyez souvent des gens faire, c'est qu'ils vérifient l'existence de la fonction X, puis sur cette base, ils supposent que la fonction se comportera d'une certaine manière dans tous les navigateurs qui ont cette fonction.

Je ne dis rien dans le sens où la détection de fonctionnalités n'est pas une bonne chose (si elle est utilisée correctement), mais je me demande pourquoi la détection de navigateur est généralement immédiatement rejetée même si cela semble logique. Je me demande si c'est une autre chose à la mode à dire.

43
Jan Zich

Il me semble que la détection du navigateur a été largement désapprouvée depuis this post par Resig il y a quelques années. Les commentaires de Resig étaient cependant spécifiques aux bibliothèques/code de cadre, c'est-à-dire au code qui sera consommé par d'autres applications/sites [spécifiques au domaine].

Je pense que la détection des fonctionnalités est sans aucun doute un bon ajustement pour les bibliothèques/frameworks . Pour les applications spécifiques à un domaine, je ne suis cependant pas sûr que la détection du navigateur soit si mauvaise. Il convient pour contourner les caractéristiques de navigateur connues qui sont difficiles à détecter, ou pour les navigateurs qui ont des bogues dans leur implémentation de la fonctionnalité elle-même. Moments où la détection du navigateur est appropriée:

  • les sites/applications qui ne sont pas multi-navigateurs et qui doivent afficher un avertissement/une boîte de dialogue/une page différente s'adaptant au navigateur de ce client. Ceci est courant dans les applications héritées.
  • Banques ou sites privés avec des politiques strictes sur les navigateurs et les versions pris en charge (pour éviter les exploits de sécurité connus qui peuvent compromettre les données de l'utilisateur)
  • micro-optimisations: parfois un navigateur est ridiculement plus rapide que les autres lorsqu'il effectue une opération d'une certaine manière. Selon votre base d'utilisateurs, il peut être avantageux de créer une branche sur ce navigateur/cette version en particulier.
  • Manque de transparence png dans IE6
  • de nombreux problèmes d'affichage/de rendu (lire: IE support css) qui ne sont observés que dans des versions de navigateur spécifiques et vous ne savez pas vraiment quelle fonctionnalité tester.

Cela dit, il y a quelques pièges majeurs (probablement commis par la plupart d'entre nous) à éviter lors de la détection du navigateur.

26
Crescent Fresh

Voici un bon article expliquant en quoi la détection des fonctionnalités est supérieure à bien des égards au reniflement du navigateur.

La vérité est que le reniflement est extrêmement fragile. Elle est fragile en théorie, car elle repose sur une chaîne arbitraire userAgent, puis associe pratiquement cette chaîne à un certain comportement. C'est aussi fragile dans la pratique, comme le montre le temps. Tester chaque version majeure et mineure de dizaines de navigateurs et essayer d'analyser les numéros de build de certaines de ces versions n'est pas pratique du tout; Tester certains comportements pour les bizarreries, en revanche, est beaucoup plus robuste. Les tests de fonctionnalités, par exemple, détectent souvent des bogues et des incohérences que les fournisseurs de navigateurs copient les uns des autres.

D'après ma propre expérience, en corrigeant Prototype.js dans IE8, je sais que 90% des problèmes auraient pu être évités si nous n'avions pas reniflé en premier lieu.

En corrigeant Prototype.js, j'ai découvert que certaines des fonctionnalités à tester sont en fait très courantes parmi les bibliothèques JS, j'ai donc fait une petite collection de tests de fonctionnalités communes pour quiconque souhaite se débarrasser du reniflement .

23
kangax

La solution idéale serait d'avoir une combinaison de détection de fonctionnalités et de navigateur. Le premier tombe en panne à cause des points que vous avez mentionnés et le second parce que parfois les navigateurs publient de fausses informations pour "faire fonctionner les choses".

Mozilla a un excellent Browser Detection Primer qui pourrait également vous être utile.

From wikipedia "À divers moments de son histoire, l'utilisation du Web a été dominée par un navigateur dans la mesure où de nombreux sites Web sont conçus pour fonctionner uniquement avec ce navigateur particulier, plutôt que selon les normes des organismes tels que le W3C et l'IETF. Ces sites incluent souvent du code de "reniflage de navigateur", qui modifie les informations envoyées en fonction de la chaîne User-Agent reçue. Cela peut signifier que les navigateurs moins populaires ne reçoivent pas de contenu complexe, même s'ils peuvent être capable de le traiter correctement ou, dans des cas extrêmes, a refusé tout le contenu. Ainsi, divers navigateurs "masquent" ou "usurpent" cette chaîne, afin de s'identifier comme autre chose à un tel code de détection; souvent, l'identité réelle du navigateur est alors incluse plus tard dans la chaîne. "

5
Joshua