Web Storage : stockage des données dans le navigateur

Web Storage : stockage des données dans le navigateur Introduits avec HTML5, Web Storage ou DOM Storage apporte une alternative aux cookies en matière de stockage de données locales. Faisons un tour du propriétaire !


Stockage des données locales

Web Storage est une solution adaptée aux besoins actuels de stockage de données variées, dans le navigateur. C'est aussi une technique plus puissante que les cookies, qui sont limités en taille (quelques Ko contre plusieurs Mo pour Web Storage) et qui engendrent un trafic HTTP supplémentaire pour chaque requête (que ce soit pour demander la page web, une image, une feuille de styles, un fichier javaScript, etc).

Web Storage met à disposition deux interfaces nommées sessionStorage et localStorage dont la seule différence concerne la persistance des données. Ces dernières ne sont plus véhiculées sur le réseau HTTP et elles sont facilement accessibles (lecture, modifications et suppression) pour la programmation en JavaScript.

 Stockage de session sessionStorage

L'interface sessionStorage mémorise les données sur la durée d'une session de navigation, et sa portée est limitée à la fenêtre ou l'onglet actif. Lors de sa fermeture, les données sont effacées. Contrairement au cookies, il n'y a pas d'interférence. Chaque stockage de session est limité à un domaine.

 Stockage local localStorage

L'interface localStorage mémorise les données sans limite de durée de vie. Contrairement à sessionStorage, elles ne sont pas effacées lors de la fermeture d'un onglet ou du navigateur. La portée de localStorage est de facto plus large  : il est possible de l'exploiter à travers plusieurs onglets ouverts pour le même domaine ou plusieurs fenêtres ; à partir du moment où il s'agit bien sûr du même navigateur.


Il n'y a pas de partage des données Web Storage entre les différents navigateurs qui peuvent être installés sur une même machine.


Usages et précautions

Le stockage de données dans le navigateur web se prête à différentes applications, particulièrement lorsqu'il s'agit d'exécuter des traitements sans faire intervenir le serveur, ou lorsqu'il faut mémoriser facilement de petites quantités de données pour l'utilisateur pour les faire persister durant sa navigation. Parmi ces avantages :

 stocker rapidement des données en cache sans faire intervenir le serveur (par exemple via AJAX),
 augmenter la performance ressentie et faciliter les développements,
 se passer des cookies et du trafic HTTP supplémentaire qu'ils représentent (un cookie est envoyé à chaque requête effectuée sur un domaine),
 exploiter un espace alloué plus important que la limite imposée par les cookies (fixée à 4 Ko),
 retrouver des données immédiatement à la reconnexion ou les mémoriser pour éviter la perte s'il y a déconnexion.

Attention : les données ne sont pas cryptées, accessibles facilement à tout utilisateur ayant accès au navigateur, et modifiables de la même façon. Il ne faut donc pas y placer d'informations sensibles.

Pour ces raisons et d'autres, certains navigateurs exigent de consulter la page appelant le stockage via un domaine, (c'est-à-dire avec une url en http://, que ce soit localhost ou bien un nom de domaine complet) et non pas en fichier local (adresse file://). Sinon, une exception de sécurité peut être déclenchée. Ceci peut sembler logique car les données sont en théorie attachées à un domaine.

Comment y accéder ?

Hormis les spécificités concernant la persistance des données, les méthodes d'accès sont communes :

 setItem(clé,valeur) : stocke une paire clé/valeur,
 getItem(clé) : retourne la valeur associée à une clé,
 removeItem(clé) : supprime la paire clé/valeur en indiquant le nom de la clé,
 key(index) : retourne la clé stockée à l'index spécifié,
 clear() : efface toutes les paires.

Pour agrémenter le tout, la propriété .length renvoie le nombre de paires stockées.

La console Javascript des navigateurs est un outil essentiel pour tester et vérifier le bon fonctionnement de Web Storage.

Note : Les exemples suivants se basent sur sessionStorage mais fonctionneront de la même façon avec localStorage.

 Stockage

 sessionStorage.setItem("couleur","vert")

 Le premier argument de setItem est la clé (toujours de type String). Elle précise l'endroit où sont stockées les données afin de pouvoir les y retrouver ultérieurement.

 Récupération

 var couleur = sessionStorage.getItem("couleur");

Grâce à la clé initialement créée avec setItem, il est possible de récupérer facilement les données. Ces dernières sont renvoyées sous la forme d'une chaîne de caractères.

 Suppression

 sessionStorage.removeItem("couleur");

Nous supprimons l'élément de session "couleur".

 Suppression totale

 sessionStorage.clear();

Suppression complète de toutes les valeurs de session.

 Accès direct

Dans la plupart des situations, les variables seront accessibles directement en tant que membres de l'interface.

sessionStorage.couleur = "vert";
console.log(sessionStorage.couleur);



Examen et espace alloué

L'espace local alloué, bien que considérablement supérieur à celui disponible via un cookie est cependant limité. Personne ne tient à voir son disque dur submergé de données créées par des milliers de sites consultés. Il faut donc gérer cet espace raisonnablement avec efficacité et parcimonie. Par défaut, Internet Explorer alloue 10 Mo par espace de stockage, et les autres navigateurs (Firefox, Chrome, Opera, Safari) 5 Mo par domaine. En réalité, par mesure de sécurité, on considère l'origine de la page, c'est-à-dire que sont également distingués tous les sous-domaines, ainsi que le port ou le mode de connexion (HTTPS s'il y a lieu). Une exception QUOTA_EXCEEDED_ERR est déclenchée si le quota est atteint.

Le navigateur peut aussi très bien choisir de demander l'autorisation à l'utilisateur au préalable avant d'accueillir des données supplémentaires, et d'incrémenter la limite au fur et à mesure. C'est une option proposée par Opera, dans les paramètres webstorage qui sont accessibles à l'adresse opera:webstorage et qui offrent un contrôle fin, domaine par domaine.

webstorageopera
Web Storage sous Opera © Alsacreations / Creative Commons

Les outils de développement et diverses consoles peuvent donner accès à des vues détaillées du stockage. Par exemple sous Chrome, l'onglet Resources :
 

webstoragechrome
Gestion du Web Storage sous Chrome © Alsacreations / Creative Commones


Ainsi que sous Opera Dragonfly dans l'onglet Stockage :

operadragonfly
Gestion du Web Storage sous Opera Dragonfly © Alsacreations / Creative Commons


Internet Explorer 10 est encore un peu avare en informations, présentées au format brut, mais un outil d'exploration se retrouve facilement en entrant sessionStorage dans la console et en cliquant sur le lien proposé.
 

ie10 webstorage
Outil de gestion du Web Storage sous IE10. © Alsacreations / JDN Solutions



Démonstration

Une première application peut être la mémorisation de champs de formulaire, pour stocker les données entrées par l'utilisateur. Bien que ceci soit applicable à toute variable manipulée en JavaScript.

Pour ceci, l'événement change sur <textarea> est sollicité pour stocker la valeur courante de l'élément dans sessionStorage.message.

<textarea id="message" name="message" 
onchange="sessionStorage.message=this.value"></textarea>


Notez que cette façon de faire est très compacte mais n'est pas des plus esthétiques car le code JavaScript se retrouve "mélangé" au contenu HTML de la page. L'idéal serait de placer cette instruction dans un script externe, ou en fin de document. jQuery peut aussi être mis à contribution pour parvenir à cet objectif.

<script>
// Détection du support
if(typeof sessionStorage!='undefined') {
 if('message' in sessionStorage) {
   alert("Message récupéré");
   document.getElementById('message').value = sessionStorage.getItem('message');
 }
} else {
 alert("sessionStorage n'est pas supporté");
}
</script>


Voir la Démonstration


Un deuxième exemple très simple à mettre en place est celui d'un compteur de visites.

<p>Vous avez vu cette page <span id="visites"></span> fois</p>

Le principe est :

 aller interroger la clé visites dans localStorage dès le chargement du document,
 effectuer toutes les vérifications nécessaires (est-ce qu'il y a déjà quelque chose stocké à cet emplacement, peut-on convertir cette chaîne de texte en nombre entier),
 incrémenter le compteur,
 le stocker à nouveau au même emplacement pour le conserver,
 afficher la valeur à un emplacement dans la page.

<script>
// Détection
if(typeof localStorage!='undefined') {
 // Récupération de la valeur dans web storage
 var nbvisites = localStorage.getItem('visites');
 // Vérification de la présence du compteur
 if(nbvisites!=null) {
   // Si oui, on convertit en nombre entier la chaîne de texte qui fut stockée
   nbvisites = parseInt(nbvisites);
 } else {
   nbvisites = 1;
 }
 // Incrémentation
 nbvisites++;
 // Stockage à nouveau en attendant la prochaine visite...
 localStorage.setItem('visites',nbvisites);
 // Affichage dans la page
 document.getElementById('visites').innerHTML = nbvisites;
} else {
 alert("localStorage n'est pas supporté");
}
</script>

Pour l'affichage, cet exemple se sert de l'identifiant id et de la fonction getElementById() pour le cibler, afin d'accéder à sa propriété innerHTML, c'est-à-dire son contenu HTML interne, modifiable.

Attention : cette information restera spécifique et locale au visiteur, ne sera pas échangée avec le serveur (hors utilisation d'Ajax par exemple), et donc ne pourra être exploitée pour établir des statistiques générales.

Voir la Démonstration 

Utilisation de JSON

Web Storage est bien pratique pour stocker de simples chaînes de texte. Lorsqu'il s'agit de manipuler des données plus complexes, entre autres des objets JavaScript, il faut les linéariser au préalable en chaînes de texte puisque Web Storage n'accepte que ce type de données. Le format JSON (JavaScript Object Notation) est la solution de prédilection. Deux méthodes équipent les navigateurs modernes : JSON.stringify() qui prend en paramètre un objet et renvoie une chaîne de texte linéarisée, et son inverse JSON.parse() qui reforme un objet à partir de la chaîne linéarisée. Des frameworks populaires tels que jQuery sont équipés de fonctions similaires (parseJSON) pour les anciens navigateurs qui ne seraient pas équipés en natifs de telles méthodes de conversion.

 Stockage

var monobjet = {
 propriete1 : "valeur1",
 propriete2 : "valeur2"
};
var monobjet_json = JSON.stringify(monobjet);
sessionStorage.setItem("objet",monobjet_json);

 Lecture

var monobjet_json = sessionStorage.getItem("objet");
var monobjet = JSON.parse(monobjet_json);
// Affichage dans la console
console.log(monobjet);


Dans le cadre de la lisibilité de cette démonstration, cet exemple de code ne fait appel que modestement à JSON, il serait possible de l'exploiter de façon beaucoup plus complexe et évoluée en fonction de la quantité de données à stocker et de leur provenance.

Voir la Démonstration

Prise en charge
 

 
Navigateurs prenant en charge Web Storage
Navigateur Versions
Source : Alsacreations
Internet Explorer 8+
Firefox 3.5+
Chrome 5+
Safari 4+
Opera 10.5+


Pour les versions d'Internet Explorer antérieures à IE8, il existe une interface nommée userData qui alloue 1 Mo par domaine et qui fonctionne sensiblement de la même manière. Pour l'exploiter, il faudra cependant adapter les fonctions au cas par cas, ou bien passer par un framework unifiant toutes les méthodes d'appel en fonction du stockage disponible.

Aller plus loin

L'API prévoit aussi des événements storage pour être notifié à chaque changement opéré dans l'espace alloué. Ceux-ci ne sont pas encore très répandus.

Pour mettre en place des stockages plus évolués, pour des données binaires ou bien du point de vue de la structure et des opérations de recherche, tri et maintenance, deux approches coexistent :

 WebSQL dont la spécification est au point mort et qui ne sera pas maintenu à long terme ni intégré à Firefox et Internet Explorer, mais qui a été implémenté par WebKit et Opera. Cette tentative faisait entrer le langage SQL côté client, ce qui était compréhensible pour les développeurs utilisant déjà les bases côté serveur (MySQL, etc) mais n'est pas conforme à l'esprit des différents standards du web : cela nécessiterait de spécifier totalement SQL ou un sous-ensemble tel que SQLite ce qui n'est pas le rôle du W3C.

 IndexedDB (Indexed Database) revêt une approche totalement orientée vers JavaScript, sans SQL, avec de la manipulation d'objets. Elle est cependant encore peu répandue (IE10 avec préfixe, Chrome et Firefox avec préfixe) ; et demande une phase d'apprentissage supplémentaire même pour les développeurs déjà aguerris avec SQL.

 

Article réalisé par Simon-K et dew (Alsacreations) sous licence Creative Commons