Le navigateur. Ta fenêtre sur le monde numérique. Mais c'est aussi une ville avec ses rues, ses entrepôts, ses registres secrets. Chaque onglet est un quartier. Chaque fenêtre, un district. Et toi, tu es dans l'ombre entre les murs.
12.1 Les Objets du Navigateur - Les Autorités de la Ville
window - Le Maire de la Fenêtre
// `window` est l'objet global du navigateur. Tout lui appartient.
console.log(window === this); // true (dans le scope global)
// Propriétés utiles
console.log(window.innerWidth, window.innerHeight); // Taille de la fenêtre
console.log(window.outerWidth, window.outerHeight); // Taille avec bordures
// Méthodes de contrôle
window.open('https://...'); // Ouvre un nouveau quartier (onglet/fenêtre)
window.close(); // Ferme la fenêtre (si tu l'as ouverte toi-même)
window.scrollTo(0, 100); // Descend de 100px
window.scrollBy(0, 50); // Descend encore de 50px
// Événements
window.addEventListener('resize', () => {
console.log('La fenêtre a changé de taille.');
});
window.addEventListener('beforeunload', (e) => {
// Déclenché quand l'utilisateur tente de partir
e.preventDefault();
e.returnValue = ''; // Message d'avertissement standard
return "Tu as des modifications non sauvegardées. Partir quand même ?";
});
document - Le Bureau des Archives
// `document` représente la page HTML chargée.
console.log(document.title); // Le titre de l'onglet
document.title = "Nouveau Titre"; // Le changer
// Accéder aux éléments (plus en détail dans le DOM)
console.log(document.head); // La section <head>
console.log(document.body); // La section <body>
console.log(document.documentElement); // L'élément <html> entier
// Chercher dans les archives
let premierParagraphe = document.querySelector('p');
let tousLesLiens = document.querySelectorAll('a');
// Créer un nouvel élément
let nouvelEspion = document.createElement('div');
nouvelEspion.textContent = "Observateur en place.";
document.body.appendChild(nouvelEspion);
// Le cookie jar (mais on y vient)
console.log(document.cookie); // Tous les cookies de ce domaine
navigator - La Carte d'Identité du Visiteur
// `navigator` décrit le navigateur et l'appareil de l'utilisateur.
// Le navigateur
console.log(navigator.userAgent);
// "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."
// Mais c'est facile à falsifier. Ne fais pas confiance.
console.log(navigator.language); // "fr-FR" (langue préférée)
console.log(navigator.platform); // "Win32", "MacIntel", "Linux x86_64"
// Capacités
console.log(navigator.onLine); // true/false - connecté à internet ?
console.log(navigator.geolocation); // Objet pour la localisation (si autorisée)
console.log(navigator.mediaDevices); // Accès à la webcam/micro (si autorisé)
// Plus obscures
console.log(navigator.hardwareConcurrency); // Nombre de cœurs CPU
console.log(navigator.deviceMemory); // Mémoire RAM en Go (approximatif)
// Services
navigator.clipboard.writeText("Message copié.") // Écrire dans le presse-papier
.then(() => console.log("Copié."))
.catch(err => console.error("Échec de copie :", err));
navigator.clipboard.readText() // Lire le presse-papier (permission requise)
.then(text => console.log("Collé :", text));
12.2 Stockage Local - Les Caches de la Ville
localStorage - Le Grenier Persistant
// Stocke des données dans le navigateur, même après fermeture.
// Spécifique au domaine. Max ~5-10 MB.
// Écrire (toujours des strings)
localStorage.setItem('clefSecrète', 'valeur123');
localStorage.nomAgent = 'Raven'; // Syntaxe alternative
// Lire
let clef = localStorage.getItem('clefSecrète');
let nom = localStorage.nomAgent; // Syntaxe alternative
console.log(clef, nom);
// Supprimer
localStorage.removeItem('clefSecrète');
delete localStorage.nomAgent; // Syntaxe alternative
// Vider tout
localStorage.clear();
// Stocker des objets (il faut les convertir)
let profil = { niveau: 7, actif: true };
localStorage.setItem('profil', JSON.stringify(profil));
let profilRécupéré = JSON.parse(localStorage.getItem('profil'));
// Événement quand un autre onglet du même domaine modifie le storage
window.addEventListener('storage', (event) => {
console.log(`Clef ${event.key} changée :`, event.oldValue, '→', event.newValue);
console.log('Modifié dans :', event.url);
});
sessionStorage - Le Bureau Temporaire
// Comme localStorage, mais ne survit qu'à la session.
// Ferme l'onglet = données perdues.
sessionStorage.setItem('sessionId', 'xyz789');
console.log(sessionStorage.sessionId); // "xyz789"
// Parfait pour :
// - Données temporaires de formulaire
// - État de l'application pendant la navigation
// - Token de session (même si le nom est trompeur)
Cookies - Les Tickets Contrôlés
// Les anciens. Petits (4KB max), envoyés avec chaque requête HTTP.
// Contrôlables côté serveur (HttpOnly, Secure, SameSite).
// Lire (une seule chaîne dégueu)
console.log(document.cookie); // "nom=valeur; autre=truc;"
// Écrire (formule alambiquée)
document.cookie = "utilisateur=John; path=/; max-age=3600"; // Expire dans 1h
document.cookie = "session=abc123; path=/; Secure"; // HTTPS seulement
document.cookie = "prefs=dark; path=/; SameSite=Strict"; // Protection CSRF
// Fonctions utilitaires (car l'API est primitive)
function setCookie(nom, valeur, jours) {
let expires = "";
if (jours) {
const date = new Date();
date.setTime(date.getTime() + (jours * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = `${nom}=${valeur}${expires}; path=/; SameSite=Lax`;
}
function getCookie(nom) {
const match = document.cookie.match(new RegExp('(^| )' + nom + '=([^;]+)'));
return match ? match[2] : null;
}
function deleteCookie(nom) {
document.cookie = `${nom}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
}
// Quand les utiliser ?
// - Authentification (jetons HttpOnly, Secure)
// - Préférences utilisateur simples
// - Suivi légal (avec consentement)
12.3 Navigation et Localisation - Les Cartes de la Ville
location - L'Adresse Actuelle
// `location` décrit l'URL actuelle et permet de naviguer.
console.log(location.href); // "https://example.com/page?query=1#section"
console.log(location.origin); // "https://example.com"
console.log(location.protocol); // "https:"
console.log(location.host); // "example.com"
console.log(location.hostname); // "example.com" (sans le port)
console.log(location.port); // "" ou "8080" si spécifié
console.log(location.pathname); // "/page"
console.log(location.search); // "?query=1"
console.log(location.hash); // "#section"
// Changer de lieu
location.href = "https://autre.com"; // Redirection complète
location.assign("https://autre.com"); // Pareil, avec historique
location.replace("https://autre.com"); // Sans historique (remplace)
location.reload(); // Recharger la page
location.reload(true); // Recharger sans cache
// Manipuler l'URL
location.hash = "#nouvelleSection"; // Sauter à l'ancre
location.search = "?nouvelleQuery=2"; // Changer la query string
// Détecter les changements (pour les SPAs)
window.addEventListener('popstate', (event) => {
// Quand l'utilisateur clique sur précédent/suivant
console.log('État de navigation changé :', event.state);
});
// Pour changer l'URL sans recharger (SPA)
history.pushState({page: 2}, "Titre 2", "/page2");
history - Le Registre des Déplacements
// `history` garde trace des pages visitées dans cet onglet.
console.log(history.length); // Nombre d'entrées dans l'historique
// Navigation
history.back(); // Comme le bouton "Précédent"
history.forward(); // Comme le bouton "Suivant"
history.go(-2); // Reculer de 2 pages
history.go(1); // Avancer d'1 page
// Manipuler l'historique (pour les SPAs)
history.pushState({id: 123}, "Détails", "/details/123");
// Ajoute une entrée sans recharger la page
history.replaceState({id: 456}, "Mise à jour", "/details/456");
// Remplace l'entrée actuelle
// Détecter les changements
window.onpopstate = function(event) {
console.log("État restauré :", event.state);
// Charge les données correspondant à event.state
};
// Sécurité : Tu ne peux pas LIRE l'historique complet
// (pour éviter de savoir quels sites l'utilisateur a visité).
screen - La Mesure de l'Écran
// Informations sur l'écran physique.
console.log(screen.width, screen.height); // Résolution totale
console.log(screen.availWidth, screen.availHeight); // Espace sans barre des tâches
console.log(screen.colorDepth); // Bits par pixel (24, 30, 48...)
console.log(screen.pixelDepth); // Généralement = colorDepth
console.log(screen.orientation); // Type et angle
// Détecter le changement d'orientation
screen.orientation.addEventListener('change', () => {
console.log('Nouvelle orientation :', screen.orientation.type);
});
// Verrouiller l'orientation (mobile, API expérimentale)
if (screen.orientation.lock) {
screen.orientation.lock('portrait')
.catch(err => console.log("Verrouillage refusé :", err));
}
12.4 Cas Concrets - Les Rues Obscures
Panneau de Contrôle Minimal
class PanneauContrôle {
constructor() {
this.sessionId = this._générerId();
this._initialiser();
}
_générerId() {
return 'sess_' + Math.random().toString(36).substr(2, 9);
}
_initialiser() {
// Sauvegarder la session
sessionStorage.setItem('sessionId', this.sessionId);
// Enregistrer la visite (avec date)
let visites = JSON.parse(localStorage.getItem('visites') || '[]');
visites.push(new Date().toISOString());
localStorage.setItem('visites', JSON.stringify(visites.slice(-50))); // Garder 50 max
// Suivre la position dans la page
let lastScroll = sessionStorage.getItem('lastScroll');
if (lastScroll) {
window.scrollTo(0, parseInt(lastScroll));
}
window.addEventListener('scroll', () => {
sessionStorage.setItem('lastScroll', window.scrollY);
});
}
infos() {
return {
session: this.sessionId,
écran: `${screen.width}x${screen.height}`,
navigateur: navigator.userAgent.substring(0, 50) + '...',
enLigne: navigator.onLine,
langue: navigator.language,
url: location.href
};
}
partir() {
sessionStorage.clear(); // Nettoyer le bureau temporaire
// localStorage reste (grenier persistant)
location.replace('about:blank'); // Aller nulle part
}
}
// Utilisation
let panneau = new PanneauContrôle();
console.log(panneau.infos());
Détection de Fuite (Changement d'Onglet)
let heureFocus = Date.now();
window.addEventListener('blur', () => {
heureFocus = Date.now();
console.log('Fenêtre perdue de vue.');
document.title = "⚠️ Reviens...";
});
window.addEventListener('focus', () => {
let absence = Date.now() - heureFocus;
console.log(`Retour après ${absence}ms.`);
document.title = "Surveillance active";
if (absence > 10000) { // Absent plus de 10 secondes
console.warn('Absence suspecte détectée.');
// Action : rafraîchir les données, vérifier la session...
}
});
Stockage avec Expiration (comme des Cookies)
class StockageExpirable {
setItem(key, value, minutes) {
const item = {
value,
expires: minutes ? new Date().getTime() + (minutes * 60000) : null
};
localStorage.setItem(key, JSON.stringify(item));
}
getItem(key) {
const itemStr = localStorage.getItem(key);
if (!itemStr) return null;
const item = JSON.parse(itemStr);
if (item.expires && new Date().getTime() > item.expires) {
localStorage.removeItem(key);
return null;
}
return item.value;
}
nettoyer() {
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
this.getItem(key); // La méthode supprime automatiquement si expiré
}
}
}
// Utilisation
let cache = new StockageExpirable();
cache.setItem('rapport_temp', 'Données sensibles', 5); // Expire dans 5 min
// Plus tard...
let données = cache.getItem('rapport_temp'); // null si expiré
Résumé du Module 12 :
Les Autorités :
window: Le maître de la fenêtre. Contrôle taille, navigation, événements.document: Les archives de la page. Accès au DOM, aux cookies.navigator: La carte d'identité du client. Navigateur, capacités, appareil.
Les Caches :
localStorage: Le grenier persistant (survie aux fermetures).sessionStorage: Le bureau temporaire (survie à la session).Cookies: Les vieux tickets (petits, envoyés au serveur).
La Cartographie :
location: L'adresse actuelle. Permet de naviguer et de lire l'URL.history: Le registre des déplacements dans l'onglet.screen: Les mesures de l'écran physique.
À retenir :
- Chaque outil a son usage. Ne stocke pas de tokens sensibles dans
localStorage(vulnérable au XSS). Utilise des cookiesHttpOnlypour ça. - La vie privée existe. Ne traque pas sans consentement.
- Le navigateur est un environnement hostile. Assume que les données peuvent être effacées à tout moment.
Maintenant tu connais les rues, les caches, les registres. Tu peux naviguer dans l'ombre du navigateur sans laisser de traces... ou en laissant juste celles que tu veux.