Trucsweb.com

Trucsweb.com

Javascript

Entête HTTP

RDFFav

Détecter Windows 11 avec le « Client Hints » ou conseils client

L’User-Agent est mort, vive le Client Hints avec autant d’informations sur l’utilisateur sinon davantage!Accept-CH, Critical-CH, json, entete http, requête, User-Agent, edge,chrome,Sec-CH-UA,Sec-CH-UA-Mobile,Sec-CH-UA-Full-Version,Sec-CH-UA-Platform,Sec-CH-UA-Platform-Version,Sec-CH-UA-Arch,Sec-CH-UA-Bitness,Sec-CH-UA-ModelDétecter Windows 11 avec le « Client Hints » ou conseils client

Salvador Dalí : La Persistance de la Mémoire (1931) (Auteur : Salvador Dalí)
Salvador Dalí : La Persistance de la Mémoire (1931)
L’agent utilisateur ou l’« User-Agent »

Les développeurs Web utilisent depuis toujours l’« User-Agent » (agent utilisateur) pour récupérer des informations sur l’équipement de l’utilisateur. Comme le navigateur, la version, le système d’exploitation, la langue, la résolution, etc. Le tout envoyé au serveur par le navigateur via ce qu’on appelle l’entête de la requête HTTP.

L’« User-Agent » donne aux serveurs la possibilité d’optimiser l’expérience utilisateur. Rappelez-vous les différences incroyables entre Netscape 3 et Internet Explorer 3 à l’ère du DHTML. Que dire de la révolution de Netscape 6 ou d’Internet Explorer 5 avec ses nombreuses fonctionnalités inédites que la W3C a reprises par la suite. Un vrai défi à l’époque! Si la compatibilité est aujourd’hui "plus facile" (il y a encore beaucoup d’Internet Explorer...), la méthode reste toujours très utilisée pour optimiser et personnaliser l’expérience utilisateur, notamment les images adaptées à la résolution ou à la vitesse de connexion.

Mais voilà, le développement de Chromium et Mozilla, derrière la plupart des navigateurs Web, gèle maintenant les chaînes « User-Agent » (agent utilisateur) envoyées par le navigateur. Leurs navigateurs n’enverront jamais « Windows NT 11.0 » pour indiquer que le navigateur fonctionne sous Windows 11. La raison, selon la W3C « La valeur de cet en-tête expose beaucoup plus d’informations sur l’appareil de l’utilisateur que ce qui semble approprié par défaut, d’une part, et obscurcit intentionnellement le véritable agent utilisateur afin de contourner les heuristiques côté serveur erronées, d’autre part. »

Il y a un sens temporaire dans l’expression « geler »! D’autre part, il est vrai que l’User-Agent donne beaucoup d’information, une véritable signature, emmagasinée en clair dans les fichiers journaux des serveurs. Ou encore capturé par les statistiques comme Google Analytics pour être ensuite exploité par le département du SEO. C’est aussi vrai que l’User-Agent sert aussi pour tromper les serveurs, manipulée. Il est très facile de modifier la chaîne « User-Agent et les fraudeurs s’en donnent d’ailleurs à cœur joie sans parler des engins de recherches...

Il faut quand même extraire l’information de l’User-Agent, souvent codée pour des contraintes de développement internes, il faut souvent deviner. Par exemple :

  • x11 = Linux
  • kde = konqueror
  • ppc = Mac PowerPC
  • 68k ou 68000 = Macintosh
  • windows nt 4.0 = Windows NT
  • windows nt 5.0 = Windows 2000
  • windows nt 5.1 et Windows nt 5.2 = Windows XP
  • windows nt 6.0 = Windows Vista
  • windows nt 6.1 et windows nt 7.0 = Windows 7...

Windows est vraiment un champion, mais que dire des moteurs (Gecko, Mozilla, MSIE, Safari, Chrome...) derrières les navigateurs, à en perdre son latin! Exemple d’une chaine User-Agent de Windows 11 avec Edge. Voir mon vieux code « twCompteur, mesure d’audience en ASP » pour vous donner une bonne idée du défi!

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML; like Gecko) Chrome/99.0.4844.74 Safari/537.36 Edg/99.0.1150.46 »

C’est un navigateur Mozilla, Apple, Gecko, Chrome, Safari ou Edge?

// Code pour récupérer l’User-Agent 
<script>
console.log(navigator.userAgent);
</script>

Personnellement, je n’utilise pas l’User-Agent pour personnaliser l’expérience utilisateur. Je développe toujours pour tous les navigateurs. Je teste une fonctionnalité JavaScript et même CSS avant de l’utiliser, etc. Que dire de Polyfill.io, une librairie spécialement conçue pour ça. Et le site Caniuse.com pour comparer la compatibilité des navigateurs.

J’utilise l’User-Agent dans mes statistiques pour justifier la compatibilité, pour prouver que telle résolution est largement utilisée ou tel navigateur est encore utilisé, ou que 50% des visiteurs utilisent un téléphone mobile... En d’autres mots, je pourrais me passer de ces données intrusives sans problème et me contenter de consulter un site comme whatismybrowser.com pour avoir une très bonne idée des outils en circulation.

Client Hints ou réduire les informations de l’User-Agent!

L’User-Agent est mort, vive le Client Hints
Avec autant d’informations sur l’utilisateur sinon davantage!

C’est pourquoi ils ont créé une approche dite « plus respectueuse de la vie privée » pour accéder aux informations du navigateur, le « Client Hints »! Hum, je ne suis pas convaincu d’obtenir moins d’informations personnelles comparées à la signature de l’User-Agent de ma vieille tablette Samgsung « Mozilla/5.0 (Android 7.1.1; Mobile; rv:98.0) Gecko/98.0 Firefox/98.0 »! En principe oui, on a même un exemple qui démontre bien le principe de l’offre et la demande du jeu des entêtes. Mais pour l’instant, mes scripts retournent la total, exactement comme l’exemple de browserleaks.com peu importe le niveau de « Protection contre le suivi » de mon navigateur Edge ou Chrome... Espérons, on n’est pas à une tentative près!

Selon Chrome « Feature: Reduce User Agent string information » :

« La nouvelle fonctionnalité User Agent Client Hints (ou indications, indices, conseils ou astuces du client...) fournit une source alternative aux informations de l’User-Agent. Premièrement, il fournit les informations requises uniquement lorsque le serveur le demande, faisant de toute empreinte digitale qui en dépend une empreinte active, qui peut être détectée et exploitée par le navigateur. Il fournit les informations par petits incréments, de sorte que les serveurs sont moins susceptibles de toucher à de nombreux bits d’empreintes digitales afin de comprendre un détail sur le navigateur. (par exemple, marque et version majeure). Et enfin, comme il fournit les informations par petits incréments, il nécessite moins d’analyse, il est donc moins probable que les serveurs se trompent et causent des problèmes de compatibilité. »


La définition officiel de mdn web docs « Indications du client (client hints) » :

Les indications du client sont un ensemble d’en-têtes de requêtes HTTP qu’un serveur peut demander de façon proactive à un client afin de connaître les caractéristiques spécifiques à l’appareil du client et aux préférences utilisées dans l’agent utilisateur. L’ensemble des en-têtes pour ces « indications » sont listées dans En-têtes HTTP > Indications du client.

Un serveur doit annoncer sa prise en charge de telles indications via l’en-tête Accept-CH (en-US) qui contiendra les indications du client qui l’intéressent. Lorsqu’un client qui prend en charge cette fonctionnalité reçoit cet en-tête Accept-CH, il ajoute les en-têtes d’indication correspondantes aux requêtes suivantes.

Ainsi, après avoir reçu l’en-tête Accept-CH suivant dans une réponse. Le client pourrait ajouter les en-têtes Width (en-US), Viewport-Width (en-US), et Downlink (en-US) aux requêtes suivantes.

Accept-CH: Width, Viewport-Width, Downlink

L’idée consiste à envoyer dans l’entête du document une demande d’information au navigateur.

  1. Le navigateur demande une page
  2. Le serveur retourne dans l’entête une demande d’information supplémentaire, le Client Hints
  3. Le navigateur retourne le Client Hints avec les données, s’il le veut bien (de là le meilleur respect de la vie privée)

Vous pouvez définir ces en-têtes dans n’importe quel langage backend. Et même avec l’attribut http-equiv de la balise :
Exemple de Chrome en HTML Le serveur demande la largeur de la fenêtre et la vitesse de connexion
<meta http-equiv="Accept-CH" content="Viewport-Width, Downlink" />

Pour identifier le navigateur et le système d’exploitation :
<meta http-equiv="Accept-CH" content="UA, UA-Platform, UA-Arch, UA-Model, UA-Mobile, UA-Full-Version" />


Exemple en PHP
header("accept-ch: Sec-Ch-Ua-Platform,Sec-Ch-Ua-Platform-Version");


Exemple en .NET
<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
    Response.AddHeader("Accept-CH","Sec-Ch-Ua-Platform,Sec-Ch-Ua-Platform-Version");
}
</script>


Exemple en ASP
Response.AddHeader "Accept-CH", "Sec-Ch-Ua-Platform,Sec-Ch-Ua-Platform-Version"

Exemple fichier web.config sous IIS
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="accept-ch" value="Sec-Ch-Ua-Platform,Sec-Ch-Ua-Platform-Version" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>

Exemple en Django
class ClientHintsMiddleware(MiddlewareMixin):
    def process_response(self, request, response):
        response[’accept-ch’] = "Sec-Ch-Ua-Platform,Sec-Ch-Ua-Platform-Version"
        return response

Processus

Par défaut, le navigateur envoie l’entête Sec-CH-UA dans sa requête au serveur sans les champs d’ « entropie plus élevée ». Un Client Hints partiel. Le serveur doit alors lui transmettre dans l’entête de sa réponse la demande « Accept-CH ». Par exemple Accept-CH: sec-ch-ua-platform. Lors de cette requête initiale, le navigateur enregistrera les préférences Accept-CH et lors des requêtes ultérieures inclura sec-ch-ua-platform par défaut.

Requêtes utilisant uniquement l’en-tête Accept-CH
Requêtes utilisant uniquement l’en-tête Accept-CH


À partir de Microsoft Edge version 96, vous pouvez utiliser le nouvel entête Critical-CH pour recevoir les en-têtes à haute entropie souhaités avec des performances optimisées.

Requêtes utilisant les en-têtes Critical-CH et Accept-CH
Requêtes utilisant les en-têtes Critical-CH et Accept-CH

N’oubliez pas que les préférences Critical-CH et Accept-CH persistent jusqu’à ce que les cookies de session soient effacés, ou jusqu’à ce qu’un utilisateur efface les données du site ou les cookies pour une origine donnée. Pour plus d’informations sur Critical-CH, reportez-vous à la section Fiabilité de l’indice client.

Le code : La collecte de données

La collecte des données est quant à moi plus simple avec le Client Hints, l’information n’a pas à être extraite et analysée. À part un petit ajustement à faire avec la version de Windows (platformVersion) qui nous sert, fidèle à son habitude, les versions 1 à 12 pour identifier Windows 10 et les versions 13 ou plus pour Windows 11, il suffit de savoir manipuler un fichier Json.

Bon, il y a effectivement un petit détail embêtant qui peut en rebuter plusieurs. Il suffit de lire sur le web les commentaires des développeurs qui se plaignent de la difficulté d’intégrer cette fonctionnalité à leur programme. Essentiellement en raison du délai de l’entête. Il faut attendre la deuxième réponse du navigateur avant d’avoir accès aux données! Vous pouvez utiliser la réponse du serveur « Critical-CH » (voir plus haut), mais nous verrons plus bas comment accéder à ces informations dès le premier chargement de la page en utilisant une seconde requête asynchrone en JavaScript (Ajax)...

Un autre détail important, Firefox n’offre pas cette fonctionnalité et donc pour répondre à la question chaude à l’heure d’écrire ces lignes, non c’est impossible de détecter Windows 11 avec Firefox. J’ai donc dans mon nouveau système de statistiques deux nouveaux systèmes d’exploitation « Windows 11 » et « Windows 10 ou 11 »! Il semblerait que la méthode pressentie par l’équipe de Firefox ne puisse répondre au "caractère changeant" du Client Hints « Cap Windows version in the User-Agent to 10.0 - Bugzilla ».

À part Firefox qui ne supporte pas encore le Client Hints, mais qui semble sérieux dans la démarche, laissons les majors faire semblant de se préoccuper de la vie privée. Et entrons dans les détails des données d’or et déjà disponibles! Tout part de l’API « navigator »!

Noter que la plupart de ses données requièrent une connexion sécurisée SSL!

L’objet « connection »

La propriété navigator.connection retourne l’objet « NetworkInformation » concernant des informations sur la connexion du système, comme la bande passante. Ça reste quant à moi une façon d’augmenter la précision de la signature d’un utilisateur, mais en théorie, c’est pour servir une page adaptée au type de connexion de l’utilisateur :

downlink : Renvoie l’estimation de la bande passante effective en mégabits par seconde, arrondie au multiple le plus proche de 25 kilobits par seconde.

downlinkMax : Renvoie la vitesse de liaison descendante maximale, en mégabits par seconde (Mbps), pour la technologie de connexion sous-jacente./p>

effectiveType : Renvoie le type effectif de la connexion, c’est-à-dire ’slow-2g’, ’2g’, ’3g’ ou ’4g’. Cette valeur est déterminée à l’aide d’une combinaison de valeurs de temps d’aller-retour et de liaison descendante récemment observées.

rtt : Renvoie le temps d’aller-retour effectif estimé de la connexion actuelle, arrondi au multiple de 25 millisecondes le plus proche.

saveData : Renvoie vrai si l’utilisateur a défini une option d’utilisation réduite des données sur l’agent utilisateur.

type : Renvoie le type de connexion qu’un appareil utilise pour communiquer avec le réseau. Ce sera l’une des valeurs suivantes : bluetooth, cellular, ethernet, none, wifi, wimax, other, unknown.

Exemple :
<script>
if ("connection" in navigator) {
  console.log(`Vitesse de connexion : ${navigator.connection.downlink} Mbps`);
  console.log(`Vitesse de connexion maximale : ${navigator.connection.downlinkMax} Mbps`);
  console.log(`Type de connexion : ${navigator.connection.effectiveType}`);
  console.log(`Temps de parcours : ${navigator.connection.rtt} ms`);
  console.log(`Sauvegarde autorisation : ${navigator.connection.saveData}`);
  console.log(`Type : ${navigator.connection.type}`);
  console.log(`Mémoire : ${navigator.deviceMemory}`);
} else {
  console.log('ERREUR : connection n’est pas défini');
}
</script>

Performance Timeline API

L’API Performance Timeline permet de récupérer les paramètres concernant la performance de la connexion. La durée, le type de chargement, nouvelle visite ou actualisation de la page, poids de la page... Noter qu’il s’agit d’une matrice (array).

Exemple :
<script>
if (window.performance && performance.getEntriesByType) {
  let navTiming = performance.getEntriesByType('navigation');
  console.log(`Type de chargement : ${navTiming[0].entryType}`);
  console.log(`Page :${navTiming[0].name}`);
  console.log(`Durée : ${navTiming[0].duration}`);
  console.log(`Arrivée : ${navTiming[0].type}`); //reload ou navigate
  console.log(`Poids encodé : ${navTiming[0].encodedBodySize}`);
  console.log(`Poids décodé : ${navTiming[0].decodedBodySize}`);
} else {
  console.log('ERREUR : performance n’est pas défini');
}
</script>

Navigator.geolocation

Navigator.geolocation est une propriété qui retoune un objet Geolocation donnant accès aux contenus web de localisation de l’appareil. Ceci permet à un site Internet ou à une application d’offrir des résultats personnalisés basés sur la localisation des utilisateurs comme la devise, etc. Particulièrement « Geolocation.getCurrentPosition() » compatible avec tous les navigateurs! Personnellement, je trouve l’expérience tellement intrusive, voire agressive, que je ne l’utilise jamais... Mais au moins, le navigateur demande l’autorisation. C’est la seule information que le navigateur semble protéger!

<script>
// Source mdn web docs
var options = {
  enableHighAccuracy: true,
  timeout: 5000,
  maximumAge: 0
};

function success(position) {
  console.log(`Latitude : ${position.coords.latitude}`);
  console.log(`Longitude : ${position.coords.longitude}`);
  console.log(`Précision : ${position.coords.accuracy} mètres.`);
  console.log(`Altitude : ${position.coords.altitude} mètres.`);
  console.log(`Précision d’altitude : ${position.coords.altitudeAccuracy} mètres.`);
}

function error(err) {
  console.warn(`ERREUR (${err.code}): ${err.message}`);
}

navigator.geolocation.getCurrentPosition(success, error, options);
</script>

L’objet « userAgentData »

Exemple de la réponse du navigateur par défaut, sans information sur la version du système d’exploitation :

Sec-CH-UA: "Chromium";v="92", "Microsoft Edge";v="92", "Placeholder;Browser Brand";v="99"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "Windows"

Le Client Hints complets (voir la liste complète). Le tableau suivant montre tous les entêtes de réponse du serveur Accept-CH disponibles avec exemples. C’est à dire la version 91 du navigateur Edge sous windows 10 avec une Surface Pro :

Sec-CH-UA "Chromium";v="91", "Microsoft Edge";v="91", "GREASE";v="99"
Sec-CH-UA-Mobile ?0
Sec-CH-UA-Full-Version 91.0.866.0
Sec-CH-UA-Platform Windows
Sec-CH-UA-Platform-Version 10.0
Sec-CH-UA-Arch x86
Sec-CH-UA-Bitness 64
Sec-CH-UA-Model Surface Pro
Les conseils client de l’agent utilisateur ne sont envoyés que sur des connexions sécurisées à l’aide de HTTPS.

Comme je disais plus tôt, il y a deux difficultés pour accéder aux données des conseils client. Le premier c’est l’objet navigator.userAgentData retourne une chaine JSON. Exemple du noeud « brands » :

{
  "brands": [
    {
      "brand": "Chromium",
      "version":"91"
    },
    {
      "brand": "Microsoft Edge",
      "version":"91"
    },
    {
      "brand": "GREASE",
      "version":"99"
    }
  ],
  "mobile": false 
}

Le deuxième c’est le délai avant d’obtenir les données. Contrairement aux User-Agent, les conseils client ne sont pas disponibles lors du premier chargement de la page. Il faut attendre la réponse du client. C’est pourquoi tant de développeurs ont de la difficulté à l’intégrer dans leur programmation. Certain parle d’une boucle, d’autres de la directive defer, async ou encore await. Je sais, j’ai aussi essayé. Ça fonctionne, mais pas toujours! Le temps de réponse est tellement imprévisible qu’il est impossible de prévoir le coup!

// NE FONCTIONNE PAS
let ua = await navigator.userAgentData.getHighEntropyValues(["platformVersion"])

Extraire les informations

La seule solution est effectivement d’attendre les données, mais avec un Ajax, idéalement avec une promesse de retour, c’est-à-dire Promise. Commençons par le début, et laissons la console du navigateur faire tous le travail :

<script>
if (!’userAgentData’ in navigator) {
 console.log(’userAgentData n’est pas défini!’);
} else {
 console.log(’userAgentData est défini!’);
 navigator.userAgentData.getHighEntropyValues([
   "architecture",
   "model",
   "platform",
   "platformVersion",
   "uaFullVersion",
 ]).then((ua) => {
   // Une fois le résultat reçu, afficher l’objet complet :
   console.log(ua)
 });
}
</script>

Résultat :

{
    "architecture": "x86",
    "brands": [
        {
            "brand": " Not A;Brand",
            "version": "99"
        },
        {
            "brand": "Chromium",
            "version": "99"
        },
        {
            "brand": "Microsoft Edge",
            "version": "99"
        }
    ],
    "mobile": false,
    "model": "",
    "platform": "Windows",
    "platformVersion": "14.0.0",
    "uaFullVersion": "99.0.1150.46"
}

Wow, voilà l’identification de notre foutu Windows 11! Bon, vous remarquerez que c’est indiqué la version 14. Microsoft parle de version 13 et plus!! On n’est pas encore sortie des limbes des majors, mais avouons que c’est plus clair que le vieux User-Agent. Et pas si compliqué que ça en fin de compte! Voici le code suggéré par Microsoft pour extraire l’information, toujours à l’aide d’une promesse de réponse :

<script>
navigator.userAgentData.getHighEntropyValues(["platformVersion"])
 .then(ua => {
   // Une fois le résultat reçu, extraire l'info :
   if (navigator.userAgentData.platform === "Windows") {
     // Dans ce cas-ci, seulement si c'est Windows
     const majorPlatformVersion = parseInt(ua.platformVersion.split('.')[0]);
     if (majorPlatformVersion >= 13) {
       console.log("Windows 11 ou plus");
      }
      else if (majorPlatformVersion > 0) {
        console.log("Windows 10");
      }
      else {
        console.log("Avant Windows 10");
      }
   }
   else {
     console.log("Ce n'est pas Windows");
   }
 });
</script>

Version platformVersion
Win7/8/8.1 0
Win10 1507 1
Win10 1511 2
Win10 1607 3
Win10 1703 4
Win10 1709 5
Win10 1803 6
Win10 1809 7
Win10 1903 8
Win10 1909 8
Win10 2004 10
Win10 20H2 10
Win10 21H1 10
Win10 21H2 10
Win11 13+

Petit bout de mon code perso

Ma technique personnelle consiste à créer une classe JavaScript avec les informations disponibles dès la réception de la page. En l’occurrence tout ce que l’User-Agent permet encore, les informations de connexion, etc. Et surtout d’ajouter à ma classe des fonctions pour modifier certaines valeurs, notamment la version du système d’exploitation que le navigateur recevra éventuellement à l’aide de la promesse de données de Client hints :

<script>
// Fichier : twjournaux.js
// Ma classe twUserAgent conventionnelle à l’aide du User-Agent (partiel)
// Avec les 4 fonctions pour modifier le navigateur et l’OS
var twUserAgent = (function() {
  this.setOs = function (sOsTemp) {this.twOs = sOsTemp;};
  this.setOsV = function (sOsVTemp) {this.twOsV = sOsVTemp;};
  this.setNav = function (sNavTemp) {this.twNav = sNavTemp;};
  this.setNavV = function (sNavVTemp) {this.twNavV = sNavVTemp;};
  this.twSw = screen.width;
  this.twSh = screen.height;
  this.twSc = window.screen.colorDepth;
  //...
  debogue = function() {
    // Trace pour prouver que les données ont bien été reçues
    console.log(`OS : ${twUserAgent().twOs}`);
    console.log(`OS version : ${twUserAgent().twOsV}`);
    console.log(`Navigateur : ${twUserAgent().twNav}`);
    console.log(`Navigateur version : ${twUserAgent().twNavV}`);
    console.log(`Largeur de l'écran : ${twUserAgent().twSw}`);
    console.log(`Hauteur de l'écran : ${twUserAgent().twSh}`);
    console.log(`Couleurs : ${twUserAgent().twSc});
  }
  return this;
});

var uADPlatforme,uADArchitecture,uADVersionPlateforme,uADVersionApp,uADModel;
if (navigator.userAgentData) {
  uADPlatforme = navigator.userAgentData.platform;
  navigator.userAgentData.getHighEntropyValues(["architecture","platform","platformVersion","model","uaFullVersion","fullVersionList","bitness","mobile"])
  .then(uaPV => {
    // Exécuté seulement quand les données sont disponibles
    // Extraction des données à partir de la réponse Json
    let sVersionPlateforme = parseInt(uaPV.platformVersion.split('.')[0]);
    // Conversion du numéro de version si Windows(!)
    if (uADPlatforme=="Windows") {
      if (sVersionPlateforme >= 13) {
        sVersionPlateforme = 11
      }
      else if (sVersionPlateforme > 0) {
        sVersionPlateforme = 10
      }
      else {
        sVersionPlateforme = ""
      }
    }
    let sNavigateurTemp;
    let sNavigateurVersionTemp;
    const brands = [... Object.entries(navigator.userAgentData.brands)];
    // Petite passe pour détecter le navigateur parmi la liste « brands » retournée
    // « userAgentData.brands » contient des valeurs variables dans un ordre variable,
    //   on ne peu se fier à un certain index.
    //   Mais le nom du navigateur est claire. Il suffit de le comparer :
    //   (un code qui demande un peu d’amélioration!)
    brands.forEach((brand) => {
          if (/chrome/i.test(brand[1].brand)){sNavigateurTemp = brand[1].brand;sNavigateurVersionTemp = brand[1].version;}
          if (/opera/i.test(brand[1].brand)){sNavigateurTemp = brand[1].brand;sNavigateurVersionTemp = brand[1].version;}
          // En principe, Firefox est impossible...
          if (/firefox/i.test(brand[1].brand)){sNavigateurTemp = brand[1].brand;sNavigateurVersionTemp = brand[1].version;}
          if (/samsung/i.test(brand[1].brand)){sNavigateurTemp = brand[1].brand;sNavigateurVersionTemp = brand[1].version;}
          if (/vivaldi/i.test(brand[1].brand)){sNavigateurTemp = brand[1].brand;sNavigateurVersionTemp = brand[1].version;}
          if (/brave/i.test(brand[1].brand)){sNavigateurTemp = brand[1].brand;sNavigateurVersionTemp = brand[1].version;}
          if (/maxthon/i.test(brand[1].brand)){sNavigateurTemp = brand[1].brand;sNavigateurVersionTemp = brand[1].version;}
          if (/avast/i.test(brand[1].brand)){sNavigateurTemp = brand[1].brand;sNavigateurVersionTemp = brand[1].version;}
          if (/avant/i.test(brand[1].brand)){sNavigateurTemp = brand[1].brand;sNavigateurVersionTemp = brand[1].version;}
          if (/edge/i.test(brand[1].brand)){sNavigateurTemp = brand[1].brand;sNavigateurVersionTemp = brand[1].version;}
    });
    // Modification des données de ma classe « twUserAgent » avec les nouvelles données du Client Hints.
    twUserAgent().setOs(uADPlatforme);
    twUserAgent().setOsV(sVersionPlateforme);
    twUserAgent().setNav(sNavigateurTemp);
    twUserAgent().setNavV(sNavigateurVersionTemp);
    if (document.getElementById("oCompteur").getAttribute(’data-debogue’)=="1") {
      // Trace du résultat final en mode débogage
      twUserAgent().debogue();
    }
    // Vous pouvez ajouter ici un code pour emmagasiner les données sur un serveur
    // Par exemple, ce code qui respecte le (Content-Security-Policy)...
    // var oScript = document.createElement("script");
    // oScript.async = true;
    // oScript.src = ’script.php?s=[données]’;
    // document.body.appendChild(oScript);
  });
} else {
  // Méthode conventionnel pour détecter le navigateur et le système d'exploitation...
  // Seulement pour l’exemple
  twUserAgent().setOs("Plateforme");
  twUserAgent().setOsV("Version de la plateforme");
  twUserAgent().setNav("Navigateur");
  twUserAgent().setNavV("Version du navigateur");
  if (document.getElementById("oCompteur").getAttribute(’data-debogue’)=="1") {
    // Trace du résultat final en mode débogage
    twUserAgent().debogue();
  }
}
</script>

// Fichier HTML
// Balise pour afficher un compteur par exemple avec paramètre
//   ici pour activer un mode débogage
<div id="oCompteur" data-debogue="1"></div>
<script defer src="/neural/js/twjournaux.js?v3.6.0"></script>

Il y a évidemment d’autres données de disponibles, je vais au fil du temps bonifier ce script. Pour vous donner une bonne idée, consulter le page Client Hints de Browserleaks.com qui extrait toutes les données.


Conclusions

Voilà, il ne vous reste plus qu’à utiliser ou stocker ses données dans vos fichiers journaux! Je ne saurais dire ce qu’il y a de vraiment nouveau, mais on n’a pas le choix, c’est tout! Il y a tas de capitaines dans un seul navire! Sinon, ça reste encore Beta comme outils, la compatibilité n’est pas au rendez-vous. Certes Firefox, mais aussi côté serveur. Un exemple sous IIS en ASP classique. Voilà tout ce qu’on a sous la main. Comme vous pouvez le constater, j’ai beau actualiser la page, la version du système d’exploitation n’est jamais disponible, peu importe le navigateur :

HTTP_SEC_CH_UA : <%=Request.ServerVariables("HTTP_SEC_CH_UA")%><br />
HTTP_SEC_CH_UA_MOBILE : <%=Request.ServerVariables("HTTP_SEC_CH_UA_MOBILE")%><br />
HTTP_SEC_CH_UA_PLATFORM : <%=Request.ServerVariables("HTTP_SEC_CH_UA_PLATFORM")%><br />
HTTP_Sec_CH_UA_Full_Version : <%=Request.ServerVariables("HTTP_Sec_CH_UA_Full_Version")%><br />
HTTP_Sec_CH_UA_Full_Version_List : <%=Request.ServerVariables("HTTP_Sec_CH_UA_Full_Version_List")%><br />
Ce qui retourne avec un navigateur compatible :
HTTP_SEC_CH_UA : " Not A;Brand";v="99", "Chromium";v="99", "Microsoft Edge";v="99"
HTTP_SEC_CH_UA_MOBILE : ?0
HTTP_SEC_CH_UA_PLATFORM : "Windows"
HTTP_Sec_CH_UA_Full_Version : 
HTTP_Sec_CH_UA_Full_Version_List : 

Merci à Brett de whatismybrowser.com pour son aide!

Références
, Analyste programmeurConception oznogco multimédia (http://oznogco.com), Trucsweb
Dernière mise à jour :

Commentaires

Ajouter un commentaire
Votre adresse de courriel ne sera pas publiée. * L'astérisque indique les champs obligatoires.
Votre évaluation du tutoriel

10/10 sur 1 revues.
       Visites : 4979 - Pages vues : 5107
X

Trucsweb.com Connexion

Connexion

X

Trucsweb.com Mot de passe perdu

Connexion

X

Trucsweb.com Conditions générales

Conditions

Responsabilité

La responsabilité des Trucsweb.com ne pourra être engagée en cas de faits indépendants de sa volonté. Les informations mises à disposition sur ce site le sont uniquement à titre purement informatif et ne sauraient constituer en aucun cas un conseil ou une recommandation de quelque nature que ce soit.

Aucun contrôle n'est exercé sur les références et ressources externes, l'utilisateur reconnaît que les Trucsweb.com n'assume aucune responsabilité relative à la mise à disposition de ces ressources, et ne peut être tenue responsable quant à leur contenu.

Droit applicable et juridiction compétente

Les règles en matière de droit, applicables aux contenus et aux transmissions de données sur et autour du site, sont déterminées par la loi canadienne. En cas de litige, n'ayant pu faire l'objet d'un accord à l'amiable, seuls les tribunaux canadien sont compétents.

X

Trucsweb.com Trucsweb

X

Trucsweb.com Glossaire

X

Trucsweb.com Trucsweb

X

Trucsweb.com Trucsweb

Conditions

Aucun message!

Merci.

X
Aucun message!
X

Trucsweb.com Créer un compte

Créer un compte

.
@