13
LocalStorage
Persistance des données
Le Web Storage API fournit des mécanismes de stockage côté client : localStorage (persistant) et sessionStorage (temporaire). Essentiel pour sauvegarder des préférences utilisateur et des données hors ligne.
📦 localStorage vs sessionStorage
| Caractéristique | localStorage | sessionStorage |
|---|---|---|
| Persistance | ✅ Permanent (jusqu'à suppression manuelle) | ⏱️ Temporaire (fin de session) |
| Portée | Partagé entre tous les onglets du domaine | Isolé par onglet |
| Capacité | ~5-10 MB (selon navigateur) | ~5-10 MB (selon navigateur) |
| Cas d'usage | Préférences, thème, cache | Formulaires multi-étapes, panier temporaire |
🔧 Opérations de Base
// CRÉER / MODIFIER
localStorage.setItem("username", "Alice");
sessionStorage.setItem("tempData", "xyz");
// LIRE
const user = localStorage.getItem("username"); // "Alice"
const temp = sessionStorage.getItem("tempData"); // "xyz"
// SUPPRIMER UNE CLÉ
localStorage.removeItem("username");
// TOUT SUPPRIMER
localStorage.clear();
sessionStorage.clear();
// VÉRIFIER L'EXISTENCE
if (localStorage.getItem("theme")) {
// La clé existe
}
// NOMBRE D'ÉLÉMENTS
console.log(localStorage.length); // 0, 1, 2...
// ACCÉDER PAR INDEX
const key = localStorage.key(0); // Nom de la 1ère clé
const value = localStorage.getItem(key);
📋 Stocker des Objets (JSON)
// ❌ ERREUR FRÉQUENTE : Stocker directement un objet
const user = { name: "Alice", age: 25 };
localStorage.setItem("user", user);
// Stocke "[object Object]" → INUTILISABLE !
// ✅ SOLUTION : Sérialiser avec JSON.stringify
localStorage.setItem("user", JSON.stringify(user));
// RÉCUPÉRATION : Désérialiser avec JSON.parse
const savedUser = localStorage.getItem("user");
const parsedUser = savedUser ? JSON.parse(savedUser) : null;
// PATTERN : Helper Functions
const storage = {
set(key, value) {
localStorage.setItem(key, JSON.stringify(value));
},
get(key, defaultValue = null) {
const item = localStorage.getItem(key);
try {
return item ? JSON.parse(item) : defaultValue;
} catch {
return defaultValue;
}
},
remove(key) {
localStorage.removeItem(key);
}
};
// Usage
storage.set("config", { theme: "dark", lang: "fr" });
const config = storage.get("config", { theme: "light", lang: "en" });
💼 Cas d'Usage Pratiques
// 1. THÈME DARK/LIGHT PERSISTANT
function saveTheme(theme) {
localStorage.setItem("theme", theme);
document.body.className = theme;
}
function loadTheme() {
const theme = localStorage.getItem("theme") || "light";
document.body.className = theme;
}
// Au chargement de la page
loadTheme();
// 2. FORMULAIRE MULTI-ÉTAPES (sessionStorage)
function saveDraft() {
const formData = {
step1: { name: document.getElementById("name").value },
step2: { email: document.getElementById("email").value }
};
sessionStorage.setItem("formDraft", JSON.stringify(formData));
}
function loadDraft() {
const draft = sessionStorage.getItem("formDraft");
if (draft) {
const data = JSON.parse(draft);
// Remplir les champs
}
}
// 3. HISTORIQUE D'ACTIONS (avec limite)
function addToHistory(action) {
const history = JSON.parse(localStorage.getItem("history") || "[]");
history.unshift(action); // Ajouter au début
// Limiter à 10 dernières actions
if (history.length > 10) history.pop();
localStorage.setItem("history", JSON.stringify(history));
}
// 4. CACHE AVEC EXPIRATION
function cacheWithExpiry(key, value, ttlMinutes) {
const item = {
value: value,
expiry: Date.now() + (ttlMinutes * 60 * 1000)
};
localStorage.setItem(key, JSON.stringify(item));
}
function getCachedItem(key) {
const itemStr = localStorage.getItem(key);
if (!itemStr) return null;
const item = JSON.parse(itemStr);
if (Date.now() > item.expiry) {
localStorage.removeItem(key);
return null;
}
return item.value;
}
🎮 Playground Storage
Testez localStorage en temps réel. Les données persisteront même après rechargement de la page.
Sélectionnez une action
📡 Storage Event (Synchronisation entre onglets)
// Écouter les changements de localStorage dans AUTRES onglets
window.addEventListener('storage', (e) => {
console.log('Clé modifiée:', e.key);
console.log('Ancienne valeur:', e.oldValue);
console.log('Nouvelle valeur:', e.newValue);
console.log('URL:', e.url);
// Exemple : Synchroniser le thème
if (e.key === 'theme') {
document.body.className = e.newValue;
}
});
// ⚠️ ATTENTION : L'événement ne se déclenche PAS dans l'onglet qui a modifié le storage
// Il ne se déclenche que dans les AUTRES onglets du même domaine
Best Practice : Créez des helpers pour sérialiser/désérialiser automatiquement.
Utilisez
try/catch lors du parsing JSON pour éviter les erreurs. Préfixez vos clés (ex:
app_theme) pour éviter les conflits. Utilisez sessionStorage pour les données
sensibles temporaires.
⚠️ Sécurité : Ne stockez JAMAIS de mots de passe, tokens d'authentification ou données
sensibles dans
localStorage ou sessionStorage. Ces storages sont vulnérables
aux attaques XSS (Cross-Site Scripting). Pour l'authentification, utilisez des cookies
HttpOnly et Secure.
⚠️ Limites : Les données sont stockées en tant que strings uniquement.
La capacité est limitée (~5-10MB). Les opérations sont synchrones et peuvent bloquer le
thread. Pour de grandes quantités de données, utilisez IndexedDB.