Le navigateur du visiteur expose une partie de ses informations à travers un seul objet JavaScript : navigator. On y trouve son nom présumé, la langue de l'interface, l'état de la connexion, et une chaîne de caractères censée l'identifier précisément — le fameux user-agent.
Le problème, c'est que la plupart de ces informations ont été pensées dans les années 1990, à l'époque où Netscape et Internet Explorer se livraient une guerre de navigateurs. Depuis, les navigateurs ont menti, les standards ont changé, et certaines propriétés ne servent plus à rien. Ce tutoriel garde volontairement le cadre historique — détecter Firefox, Chrome ou l'ancien Internet Explorer — pour comprendre comment navigator fonctionne, mais chaque étape signale ce qui est encore fiable aujourd'hui et ce qui ne l'est plus.
Si les objets JavaScript en général ne vous sont pas familiers, la page introduction aux objets de JavaScript pose les bases avant d'aller plus loin.
Étape 1 — Lister les informations de base exposées par le navigateur : que peut-on lire via navigator ?
Définition : navigator est un objet unique, accessible depuis n'importe quelle page, qui regroupe des informations sur le navigateur et son environnement — connexion internet, langue, cookies, chaîne d'identification.
Il n'y a qu'un seul navigator par page, au même titre qu'il n'y a qu'un seul window. Pas besoin de le créer ni de l'importer, il existe déjà dès que le script s'exécute dans un navigateur — ce qui, au passage, exclut Node.js : si vous testez ce code ailleurs que dans un fichier HTML ouvert par un navigateur, navigator n'existera tout simplement pas.
Exemple : 📋 Copier le code
<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Informations de base du navigateur</title>
</head>
<body>
<p id="resultat">Chargement...</p>
<script>
const infos = {
"user-agent": navigator.userAgent,
"langue préférée": navigator.language,
"connecté à internet": navigator.onLine,
"cookies activés": navigator.cookieEnabled,
"plateforme signalée": navigator.platform
};
let lignes = "";
for (const cle in infos) {
lignes += "<p><strong>" + cle + " :</strong> " + infos[cle] + "</p>";
}
document.getElementById("resultat").innerHTML = lignes;
</script>
</body>
</html>
Résultat attendu :
user-agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 langue préférée : fr-FR connecté à internet : true cookies activés : true plateforme signalée : Win32
Enregistrez ce code dans un fichier navigator-infos-base.html et ouvrez-le directement dans votre navigateur — un double-clic sur le fichier suffit, pas besoin de serveur. Le résultat ci-dessus correspond à Chrome sous Windows ; sur votre machine, chaque ligne changera selon le navigateur, le système d'exploitation et les réglages de langue. C'est normal, ces valeurs décrivent votre environnement, pas le mien.
⚠ Le numéro de version dans Chrome/131.0.0.0 se termine presque toujours par des zéros depuis 2022. Ce n'est pas un hasard — on y revient à l'étape 5.
Étape 2 — Afficher les propriétés historiques figées (appCodeName, appName) : pourquoi renvoient-elles toujours la même chose ?
Définition : appCodeName et appName sont deux propriétés héritées du navigateur Netscape, censées identifier le navigateur — mais tous les navigateurs actuels renvoient exactement la même valeur, quel que soit leur nom réel.
L'histoire est presque comique. Au milieu des années 1990, des sites ont commencé à vérifier appName pour savoir s'ils avaient affaire à Netscape ou à Internet Explorer, et à casser volontairement l'affichage pour l'un des deux. Pour continuer à fonctionner sur ces sites, tous les navigateurs suivants — Chrome, Firefox, Safari compris — ont fini par se faire passer pour Netscape. Cette ruse de compatibilité tient depuis trente ans.
Exemple : 📋 Copier le code
<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Propriétés figées du navigateur</title>
</head>
<body>
<p id="resultat"></p>
<script>
const texte =
"<strong>appCodeName :</strong> " + navigator.appCodeName + "<br>" +
"<strong>appName :</strong> " + navigator.appName;
document.getElementById("resultat").innerHTML = texte;
</script>
</body>
</html>
Résultat attendu :
appCodeName : Mozilla appName : Netscape
Contrairement à l'étape précédente, ce résultat est identique dans Chrome, Firefox, Edge et Safari, sur n'importe quel système. C'est le seul cas de cette page où le résultat ne varie pas d'un navigateur à l'autre — précisément parce que ces deux propriétés ne servent plus à rien pour de la détection.
Étape 3 — Vérifier la connexion et les cookies avec onLine et cookieEnabled : ces propriétés sont-elles encore fiables ?
Définition : navigator.onLine retourne un booléen qui indique si le navigateur pense être connecté à un réseau, et navigator.cookieEnabled indique si les cookies sont autorisés pour la page courante.
Ce sont, à vrai dire, les deux propriétés les plus utiles de tout l'objet navigator — parce qu'elles répondent encore vraiment à la question qu'elles posent, sans mensonge ni valeur figée. onLine teste la présence d'une connexion réseau, pas la qualité de la connexion : un Wi-Fi relié à une box débranchée renverra quand même true.
Exemple : 📋 Copier le code
<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Connexion et cookies</title>
</head>
<body>
<p id="resultat"></p>
<script>
function afficherEtat() {
const enLigne = navigator.onLine;
const cookies = navigator.cookieEnabled;
document.getElementById("resultat").innerHTML =
"<strong>En ligne :</strong> " + enLigne + "<br>" +
"<strong>Cookies activés :</strong> " + cookies;
}
afficherEtat();
// se met à jour automatiquement si la connexion change
window.addEventListener("online", afficherEtat);
window.addEventListener("offline", afficherEtat);
</script>
</body>
</html>
Résultat attendu :
En ligne : true Cookies activés : true
Ouvrez les outils de développement (F12), onglet Réseau, et cochez « Offline » : le texte affiché passe à En ligne : false sans recharger la page, grâce aux deux écouteurs online/offline ajoutés à la fin du script. Si cookieEnabled renvoie false alors que vous n'avez rien changé, un bloqueur de traceurs ou un mode de navigation restrictif est probablement en cause.
Étape 4 — Construire une fonction de détection du navigateur : comment reconnaître Chrome, Firefox, Edge ou Safari ?
Définition : la détection par user-agent consiste à chercher des mots-clés précis dans navigator.userAgent pour deviner quel navigateur exécute la page.
Le piège classique : Edge et Opera intègrent tous les deux le mot Chrome dans leur user-agent, parce qu'ils sont construits sur le même moteur, Chromium. Un test naïf du type if (ua.includes("Chrome")) identifierait donc un utilisateur d'Edge comme un utilisateur de Chrome. Il faut tester les navigateurs les plus spécifiques en premier, et Chrome en dernier.
Exemple : 📋 Copier le code
<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Détection du navigateur</title>
</head>
<body>
<p id="resultat"></p>
<script>
function detecterNavigateur() {
const ua = navigator.userAgent;
// l'ordre compte : Edge et Opera contiennent aussi "Chrome" dans leur user-agent
if (ua.includes("Edg/")) {
return "Microsoft Edge";
}
if (ua.includes("OPR/") || ua.includes("Opera")) {
return "Opera";
}
if (ua.includes("Firefox/")) {
return "Firefox";
}
if (ua.includes("Chrome/")) {
return "Chrome";
}
if (ua.includes("Safari/")) {
return "Safari";
}
return "Navigateur non reconnu";
}
document.getElementById("resultat").textContent =
"Navigateur détecté : " + detecterNavigateur();
</script>
</body>
</html>
Résultat attendu :
Navigateur détecté : Chrome
Le mot affiché dépend du navigateur qui exécute le code — Firefox affichera Firefox, Edge affichera Microsoft Edge, et ainsi de suite. Testez la même page dans deux navigateurs différents pour vérifier que chacun est bien reconnu par son propre nom.
⚠ Erreur fréquente : inverser l'ordre des tests, ou tester Chrome avant Edg/. Le résultat ne provoque pas d'erreur — la fonction renvoie juste une réponse silencieusement fausse, ce qui est pire qu'un plantage, puisque rien n'avertit qu'il y a un problème.
Étape 5 — Comprendre les limites du sniffing par user-agent : pourquoi cette méthode reste-t-elle fragile en 2026 ?
Définition : le sniffing par user-agent est fragile parce que la chaîne navigator.userAgent peut être modifiée par l'utilisateur, et parce que les navigateurs eux-mêmes en réduisent volontairement le contenu depuis 2022.
Trois problèmes, pas un seul. D'abord, n'importe qui peut changer son user-agent depuis les outils de développement en deux clics — un test « anti-Internet-Explorer » se contourne donc en une seconde. Ensuite, Chrome a lancé en 2022 sa politique de réduction du user-agent : les numéros de version mineurs sont désormais gelés à 0.0.0, précisément pour empêcher le pistage fin des visiteurs. Enfin, Internet Explorer n'existe plus depuis 2022 — un vieux if (ua.includes("MSIE")) qui traîne encore dans un script ne sert plus à rien.
En résumé : le remplaçant officiel de userAgent s'appelle navigator.userAgentData, les « User-Agent Client Hints », mais il n'est disponible que dans les navigateurs à base de Chromium — Firefox et Safari ne l'implémentent pas. Pour du code qui doit fonctionner partout, la bonne question n'est donc plus « quel navigateur ? » mais « cette fonctionnalité existe-t-elle ? ».
Exemple : 📋 Copier le code
<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Détection de fonctionnalité</title>
</head>
<body>
<p id="resultat"></p>
<script>
// on ne demande pas "quel navigateur ?" mais "cette fonction existe-t-elle ?"
const supporteFetch = "fetch" in window;
const supporteClipboard = "clipboard" in navigator;
document.getElementById("resultat").innerHTML =
"<strong>API fetch disponible :</strong> " + supporteFetch + "<br>" +
"<strong>API clipboard disponible :</strong> " + supporteClipboard;
</script>
</body>
</html>
Résultat attendu :
API fetch disponible : true API clipboard disponible : true
Ce résultat est stable dans n'importe quel navigateur récent — Chrome, Firefox, Safari et Edge le supportent tous depuis plusieurs années. C'est tout l'intérêt de la détection de fonctionnalité : elle répond à la vraie question, « puis-je utiliser fetch ? », au lieu de la deviner à partir d'un nom de navigateur qui peut mentir.
Étape 6 — Tester les méthodes obsolètes javaEnabled() et taintEnabled() : que reste-t-il de ces vieilles fonctions ?
Définition : javaEnabled() et taintEnabled() sont deux méthodes historiques de navigator, conservées uniquement pour ne pas casser d'anciens scripts, et qui renvoient aujourd'hui systématiquement false.
javaEnabled() vérifiait si le plugin Java du navigateur était actif — utile à l'époque des applets Java, une technologie que plus aucun navigateur ne charge depuis la fin des années 2010. taintEnabled() venait d'un mécanisme de sécurité de JavaScript 1.2, abandonné depuis si longtemps que la plupart des développeurs actuels n'en ont jamais entendu parler. Les deux existent encore, mais uniquement pour la forme.
Exemple : 📋 Copier le code
<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Méthodes obsolètes du navigateur</title>
</head>
<body>
<p id="resultat"></p>
<script>
const java = navigator.javaEnabled();
const taint = navigator.taintEnabled();
document.getElementById("resultat").innerHTML =
"<strong>javaEnabled() :</strong> " + java + "<br>" +
"<strong>taintEnabled() :</strong> " + taint;
</script>
</body>
</html>
Résultat attendu :
javaEnabled() : false taintEnabled() : false
Contrairement aux étapes précédentes, ce résultat ne varie jamais, quel que soit le navigateur ou le système : les deux méthodes renvoient false par construction, pas par simulation d'un comportement réel. Les garder dans du code neuf n'a aucun intérêt — elles sont présentées ici pour les reconnaître si vous tombez dessus dans un vieux script.
Récapitulatif : le cycle complet en un seul script
Le script suivant réunit la détection du navigateur, la vérification de la connexion et des cookies, et un test de fonctionnalité — les trois usages réellement utiles vus dans cette page. Les propriétés figées (appCodeName, appName) et les méthodes obsolètes (javaEnabled, taintEnabled) n'y figurent pas volontairement : elles n'ont leur place que dans un contexte pédagogique, pas dans du code destiné à un site réel.
Exemple : 📋 Copier le code
<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Récapitulatif : objet Navigator</title>
</head>
<body>
<div id="resultat"></div>
<script>
function detecterNavigateur() {
const ua = navigator.userAgent;
// l'ordre compte : Edge et Opera contiennent aussi "Chrome" dans leur user-agent
if (ua.includes("Edg/")) return "Microsoft Edge";
if (ua.includes("OPR/") || ua.includes("Opera")) return "Opera";
if (ua.includes("Firefox/")) return "Firefox";
if (ua.includes("Chrome/")) return "Chrome";
if (ua.includes("Safari/")) return "Safari";
return "Navigateur non reconnu";
}
function resumerNavigateur() {
const navigateur = detecterNavigateur();
const enLigne = navigator.onLine;
const cookies = navigator.cookieEnabled;
const supporteFetch = "fetch" in window;
document.getElementById("resultat").innerHTML =
"<p><strong>Navigateur détecté :</strong> " + navigateur + "</p>" +
"<p><strong>En ligne :</strong> " + enLigne + "</p>" +
"<p><strong>Cookies activés :</strong> " + cookies + "</p>" +
"<p><strong>API fetch disponible :</strong> " + supporteFetch + "</p>";
}
resumerNavigateur();
window.addEventListener("online", resumerNavigateur);
window.addEventListener("offline", resumerNavigateur);
</script>
</body>
</html>
Résultat attendu :
Navigateur détecté : Chrome En ligne : true Cookies activés : true API fetch disponible : true
Enregistrez ce script dans navigator-recapitulatif.html et ouvrez-le : les quatre lignes s'affichent immédiatement, et les deux premières se mettent à jour toutes seules si vous basculez votre connexion en mode hors ligne depuis les outils de développement.
Par carabde : 30 mars 2014 | Mis à jour le 27 septembre 2026