Les objets de stockage Web localStorage et sessionStorage permettent dâenregistrer les paires clé/valeur dans le navigateur.
Ce qui est intéressant à leur sujet, câest que les données survivent à une actualisation de la page (pour sessionStorage) et même à un redémarrage complet du navigateur (pour localStorage). Nous verrons cela très bientôt.
Nous avons déjà des cookies. Pourquoi des objets supplémentaires ?
- Contrairement aux cookies, les objets de stockage Web ne sont pas envoyés au serveur à chaque requête. Grâce à cela, nous pouvons stocker beaucoup plus. La plupart des navigateurs autorisent au moins 5 mégaoctets de données (ou plus) et ont des paramètres pour configurer cela.
- Contrairement aux cookies également, le serveur ne peut pas manipuler les objets de stockage via les en-têtes HTTP. Tout se fait en JavaScript.
- Le stockage est lié à lâorigine (triplet domaine/protocole/port). Autrement dit, différents protocoles ou sous-domaines impliquent différents objets de stockage, ils ne peuvent pas accéder aux données les uns des autres.
Les deux objets de stockage fournissent les mêmes méthodes et propriétés :
setItem(key, value)â stocke la paire clé/valeur.getItem(key)â récupère la valeur par clé.removeItem(key)â supprime la clé avec sa valeur.clear()â supprime tout.key(index)â récupère la clé sur une position donnée.lengthâ le nombre dâéléments stockés.
Comme vous pouvez le voir, câest comme une collection Map (setItem/getItem/removeItem), mais permet également lâaccès par index avec key(index).
Voyons voir comment ça fonctionne.
Démo localStorage
Les principales caractéristiques de localStorage sont les suivantes :
- Partagé entre tous les onglets et fenêtres dâune même origine.
- Les données nâexpirent pas. Il reste après le redémarrage du navigateur et même le redémarrage du système dâexploitation.
Par exemple, si vous exécutez ce codeâ¦
localStorage.setItem('test', 1);
â¦Et fermez/ouvrez le navigateur ou ouvrez simplement la même page dans une autre fenêtre, alors vous pouvez lâobtenir comme ceci :
alert( localStorage.getItem('test') ); // 1
Il suffit dâêtre sur la même origine (domaine/port/protocole), le chemin de lâurl peut être différent.
Le localStorage est partagé entre toutes les fenêtres avec la même origine, donc si nous définissons les données dans une fenêtre, le changement devient visible dans une autre.
Accès de type objet
Nous pouvons également utiliser un objet simple pour obtenir/définir des clés, comme ceci :
// définir la clé
localStorage.test = 2;
// obtenir la clé
alert( localStorage.test ); // 2
// supprimer clé
delete localStorage.test;
Câest autorisé pour des raisons historiques, et fonctionne plus ou moins, mais généralement déconseillé, car :
-
Si la clé est générée par lâutilisateur, elle peut être nâimporte quoi, comme
lengthoutoString, ou une autre méthode intégrée delocalStorage. Dans ce cas,getItem/setItemfonctionne correctement, tandis que lâaccès de type objet échoue :let key = 'length'; localStorage[key] = 5; // Erreur, impossible d'attribuer 'length' -
Il y a un événement
storage, il se déclenche lorsque nous modifions les données. Cet événement ne se produit pas pour un accès de type objet. Nous verrons cela plus loin dans ce chapitre.
Boucle sur les clés
Comme nous lâavons vu, les méthodes fournissent la fonctionnalité âget/set/remove by keyâ. Mais comment obtenir toutes les valeurs ou clés enregistrées ?
Malheureusement, les objets de stockage ne sont pas itérables.
Une façon consiste à boucler sur eux comme sur un tableau :
for (let i=0; i<localStorage.length; i++) {
let key = localStorage.key(i);
alert(`${key}: ${localStorage.getItem(key)}`);
}
Une autre façon consiste à utiliser la boucle for key in localStorage, comme nous le faisons avec des objets normaux.
Il itère sur les clés, mais génère également quelques champs intégrés dont nous nâavons pas besoin :
// mauvais essai
for(let key in localStorage) {
alert(key); // affiche getItem, setItem et d'autres éléments intégrés
}
â¦Nous devons donc soit filtrer les champs du prototype avec la vérification hasOwnProperty :
for(let key in localStorage) {
if (!localStorage.hasOwnProperty(key)) {
continue; // sauter des clés comme "setItem", "getItem" etc.
}
alert(`${key}: ${localStorage.getItem(key)}`);
}
â¦Ou récupérez simplement les clés âpropresâ avec Object.keys, puis bouclez-les si nécessaire :
let keys = Object.keys(localStorage);
for(let key of keys) {
alert(`${key}: ${localStorage.getItem(key)}`);
}
Ce dernier fonctionne, car Object.keys ne renvoie que les clés appartenant à lâobjet, en ignorant le prototype.
Chaînes uniquement
Veuillez noter que la clé et la valeur doivent être des chaînes.
Sâil sâagissait dâun autre type, comme un nombre ou un objet, il est automatiquement converti en chaîne de caractères :
localStorage.user = {name: "John"};
alert(localStorage.user); // [object Object]
We can use JSON to store objects though:
localStorage.user = JSON.stringify({name: "John"});
// un peu plus tard
let user = JSON.parse( localStorage.user );
alert( user.name ); // John
Il est également possible de transformer en chaîne lâensemble de lâobjet de stockage, par ex. à des fins de débogage :
// ajout d'options de formatage à JSON.stringify pour rendre l'objet plus beau
alert( JSON.stringify(localStorage, null, 2) );
sessionStorage
Lâobjet sessionStorage est beaucoup moins utilisé que localStorage.
Les propriétés et les méthodes sont les mêmes, mais câest beaucoup plus limité :
- Le
sessionStoragenâexiste que dans lâonglet actuel du navigateur.- Un autre onglet avec la même page aura un stockage différent.
- Mais il est partagé entre les iframes du même onglet (en supposant quâils proviennent de la même origine).
- Les données survivent à lâactualisation de la page, mais pas à la fermeture/ouverture de lâonglet.
Voyons cela en action.
Exécutez ce codeâ¦
sessionStorage.setItem('test', 1);
â¦Puis actualisez la page. Maintenant, vous pouvez toujours obtenir les données :
alert( sessionStorage.getItem('test') ); // après rafraîchissement : 1
â¦Mais si vous ouvrez la même page dans un autre onglet et réessayez, le code ci-dessus renvoie null, ce qui signifie ârien trouvéâ.
Câest exactement parce que sessionStorage est lié non seulement à lâorigine, mais également à lâonglet du navigateur. Pour cette raison, sessionStorage est utilisé avec parcimonie.
Ãvénement de stockage
Lorsque les données sont mises à jour dans localStorage ou sessionStorage, lâévénement storage se déclenche, avec les propriétés :
keyâ la clé qui a été changée (nullsi.clear()est appelé).oldValueâ lâancienne valeur (nullsi la clé vient dâêtre ajoutée).newValueâ la nouvelle valeur (nullsi la clé est supprimée).urlâ lâurl du document où la mise à jour sâest produite.storageAreaâ objetlocalStorageousessionStorageoù la mise à jour sâest produite.
Lâimportant est que lâévénement se déclenche sur tous les objets window où le stockage est accessible, sauf celui qui lâa provoqué.
Ãlaborons.
Imaginez, vous avez deux fenêtres avec le même site dans chacune. Donc localStorage est partagé entre eux.
Vous pouvez ouvrir cette page dans deux fenêtres de navigateur pour tester le code ci-dessous.
Si les deux fenêtres écoutent window.onstorage, chacune réagira aux mises à jour qui se sont produites dans lâautre.
// se déclenche sur les mises à jour effectuées sur le même stockage à partir d'autres documents
window.onstorage = (event) => {
// peut également utiliser window.addEventListener('storage', event => {
if (event.key != "now") return;
alert(event.key + ":" + event.newValue + " at " + event.url);
};
localStorage.setItem('now', Date.now());
Veuillez noter que lâévénement contient également : event.url â lâurl du document où les données ont été mises à jour.
De plus, event.storageArea contient lâobjet de stockage â lâévénement est le même pour sessionStorage et localStorage, donc event.storageArea fait référence à celui qui a été modifié. On peut même vouloir y remettre quelque chose, ârépondreâ à un changement.
Cela permet à différentes fenêtres dâune même origine dâéchanger des messages.
Les navigateurs modernes prennent également en charge Broadcast channel API, lâAPI spéciale pour la communication inter-fenêtre de même origine, elle est plus complète, mais moins prise en charge. Il existe des bibliothèques qui polyfill cette API, basée sur localStorage, qui la rendent disponible partout.
Résumé
Les objets de stockage Web localStorage et sessionStorage permettent de stocker des paires clé/valeur dans le navigateur.
cléetvaleurdoivent être des chaînes.- La limite est de 5mb+, dépend du navigateur.
- Ils nâexpirent pas.
- Les données sont liées à lâorigine (domaine/port/protocole).
localStorage |
sessionStorage |
|---|---|
| Partagé entre tous les onglets et fenêtres de même origine | Visible dans un onglet de navigateur, y compris les iframes de la même origine |
| Survit au redémarrage du navigateur | Survit à lâactualisation de la page (mais pas à la fermeture de lâonglet) |
APIÂ :
setItem(key, value)â stocke la paire clé/valeur.getItem(key)â récupère la valeur par clé.removeItem(key)â supprime la clé avec sa valeur.clear()â supprime tout.key(index)â récupère la clé sur une position donnée.lengthâ le nombre dâéléments stockés.- Utilisez
Object.keyspour obtenir toutes les clés. - Nous accédons aux clés en tant que propriétés dâobjet, dans ce cas lâévénement
storagenâest pas déclenché.
Ãvénement de stockage :
- Se déclenche sur les appels
setItem,removeItem,clear. - Contient toutes les données sur lâopération (
key/oldValue/newValue), le documenturlet lâobjet de stockagestorageArea. - Se déclenche sur tous les objets
windowqui ont accès au stockage sauf celui qui lâa généré (dans un onglet poursessionStorage, globalement pourlocalStorage).
Commentaires
<code>, pour plusieurs lignes â enveloppez-les avec la balise<pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepenâ¦)