mardi 29 novembre 2011

Storage, l'éternel problème ...

HTML5 : cap sur le stockage des données en local



Web Storage ou DOM Storage : quels avantages ?


Web Storage (ou DOM Storage) ajoute la capacité au navigateur de stocker et organiser des données locales. Ce concept initialement intégré à la spécification HTML 5, fait désormais l'objet d'une spécification séparée.

From Wikipedia, the free encyclopedia :

Web Storage and DOM Storage (Document Object Model) are web application software methods and protocols used for storing data in a web browser. Web storage supports persistent data storage, similar to cookies but with a greatly enhanced capacity[1] and no information stored in the HTTP Request Header [2]. There are 2 main web storage types, local storage and session storage, behaving like Persisted Cookies and Session Cookies accordingly.
Web storage is being standardized by the World Wide Web Consortium (W3C). It was originally part of the HTML 5specification, but is now in a separate specification.[3] It is supported by Internet Explorer 8Mozilla-based browsers (e.g., Firefox 2+, officially from 3.5),[4] Safari 4, Google Chrome 4 (sessionStorage is from 5), and Opera 10.50. As of 14 July 2010 only Opera supports the storage events.[5]

Les bénéficiaires de cette avancée sont bien entendu les applications Web qui vont tirer parti de structures facilitant la mémorisation de (relativement) grandes quantités de données sans devoir exploiter les cookies ou le dialogue constant avec une base de données distante, en Ajax par exemple.


sessionStorage et localStorage permettent de faire persister les données de l'utilisateur
Or, les cookies ne sont que des miettes. Ils sont familiers à tout un chacun, depuis les débuts du Web à destination des particuliers. Ils ont été employés pour la gestion de paniers virtuels dans le cadre de l'e-commerce, pour la mémorisation d'identifiants de sessions, et surtout pour pouvoir établir des statistiques de visites en suivant l'internaute au fil de sa navigation.

Leur inconvénient est de ne pas être adaptés au stockage local de données plus complexes :
 Ils engendrent un trafic HTTP supplémentaire en ajoutant leur contenu à chaque requête (quel que soit l'objet demandé, que les cookies lui soient utiles ou non), ce qui peut influencer les temps de réponse, notamment avec Ajax.
 Leur taille est limitée, habituellement quelques kilo-octets.

Le plugin Flash est également équipé d'un équivalent nommé Flash Local Storage, qui nécessite cependant le développement dans ce langage, qui n'est pas aussi simple d'accès, et qui reste subordonné à la présence du plugin.
Faire appel à Ajax et à une base de données côté serveur est envisageable, mais engendre un trafic réseau plus important, une exécution obligatoirement en mode connecté et une mise en place plus complexe.

accès à deux espaces de stockage







 
Accès à deux espaces de stockage © Eyrolles







 

Web Storage quant à lui met en œuvre deux objets nommés sessionStorage et localStorage pour faire persister les données de l'utilisateur respectivement durant la session ou sans limitation de durée particulière. La capacité offerte est nettement supérieure, habituellement de 5 Mo à 10 Mo par défaut, bien que cette limite puisse être modifiée au sein du navigateur. Les données ne sont alors plus véhiculées sur le réseau à chaque requête HTTP, et disposent d'une interface de programmation complète pour pouvoir y accéder en lecture, modification et suppression, de façon bien pratique.

Web Storage : Accès à deux espaces de stockage


La manipulation des objets Web Storage s'effectue exclusivement par des scripts exécutés côté client par le navigateur.
Ces données ne sont pas divulguées au travers des requêtes HTTP, lors de l'envoi ou de la réception de documents HTML, elles ne sont donc pas communiquées au serveur. Celui-ci ne peut pas non plus "directement" y écrire des informations à l'aide des en-têtes HTTP ou du langage interprété (PHP, Java, .NET, etc.).
Deux espaces de stockage existent, et diffèrent par leur portée et leur durée de vie.

Stockage de session


Le stockage de session (session storage) est destiné à la mémorisation de données ayant une courte durée de vie, dont la portée est limitée à la session active de la fenêtre (ou de l'onglet) du navigateur ainsi qu'au domaine dont elles sont issues. Il permet ainsi d'exécuter des applications Web dans des fenêtres (ou des onglets) distinct(e)s avec des ensembles de données différents sans risque d'interférences – ce qui n'est pas le cas des cookies. Les données sont effacées après la fermeture de la fenêtre (ou de l'onglet) et ne persistent pas. À l'ouverture d'une nouvelle session, dans une nouvelle fenêtre ou un nouvel onglet, le navigateur initialise un nouvel objet de stockage.

L'accès se fait via l'interface sessionStorage de type Storage, enfant direct de l'objet window, ce qui signifie qu'il s'agit d'un objet global au même titre que la plupart des autres API et interfaces d'accès aux outils de navigation (historique, cookies, etc.), et qu'il est accessible depuis un éventuel élément iframe contenu dans le document.


Local Storage



À la différence du précédent, le stockage local bénéficie d'une durée de vie plus longue puisqu'il n'est pas effacé à la fermeture du navigateur. Sa portée est étendue à toutes les pages et tous les scripts provenant du même domaine, dont il est issu ; donc virtuellement, à toutes les fenêtres et tous les onglets ouverts exploitant des pages hébergées avec le même nom de domaine. Hormis ces caractéristiques, il demeure fonctionnellement différent du stockage de session. Il est accessible via l'objet global localStorage de type Storage, enfant de l'objet window.


L'interface Storage de HTML5


Pour accéder de manière unifiée à sessionStorage et localStorage, l'interface Storage a été définie. Le modèle de données est un tableau associatif de paires clé/valeur, accessible par trois fonctions nomméessetItem(), getItem(), removeItem() :
 setItem(cle,valeur) : stocke une paire clé/valeur ;
 getItem(cle) : retourne la valeur associée à une clé ;
 removeItem(cle) : supprime la paire clé/valeur en indiquant le nom de la clé.

Toutes les valeurs sont de type chaîne de texte (String). Bien qu'elles puissent être lues directement via les propriétés de l'objet Storage, comme tout autre objet JavaScript, il est fortement recommandé de s'en tenir aux méthodes prévues à cet effet.
L'interface Storage est aussi munie d'une propriété length et de deux méthodes complémentaires :
 length : nombre total de paires clé/valeur stockées ;
 key(index) : retourne la clé stockée à l'index spécifié ;
 clear() : efface toutes les paires.


L'outil essentiel pour expérimenter Web Storage reste la console JavaScript, fournie par tous les bons navigateurs avec leurs extensions de développement, par exemple Firebug pour Firefox (onglet Console) ou les Outils de développement sous Google Chrome. Elle permet de s'assurer du bon fonctionnement de l'interface, de consulter à un moment donné l'état du stockage et de le modifier.

déroulé dans la console de firebug




Stockage, lecture, suppression avec Web Storage


Les exemples suivants exploitent à la fois stockage local et stockage de session, mais il est évidemment possible d'utiliser l'un sans faire appel à l'autre.

Stockage avec setItem()
// Mémorisation d'une valeur dans la session courante
sessionStorage.setItem("identifiant","Sibelius");
// Mémorisation d'une valeur dans le stockage local
localStorage.setItem("derniere_visite",new Date());

Le premier argument de setItem() est la clé. Elle nomme l'emplacement où l'on souhaite stocker les données pour pouvoir les y retrouver. Si une valeur numérique (par exemple 2) est utilisée comme clé, elle se voit obligatoirement convertie en chaîne de texte (soit "2") avant d'être utilisée.
Le deuxième argument est la chaîne de caractères à stocker. S'il ne s'agit pas d'une variable de type string alors le navigateur tente de convertir le tout au préalable, avec la méthode toString().


Lecture avec getItem()
// Lecture d'une clé de la session courante
var id_utilisateur = sessionStorage.getItem("identifiant");

// Affichage
alert("Identifiant utilisateur : "+id_utilisateur);

// Lecture d'une clé du stockage local
var date_visite = localStorage.getItem("derniere_visite");

// Affichage
if(date_visite!=undefined) {
alert("Dernière visite : "+date_visite);
}

La récupération du contenu est possible grâce à la clé initiale, fournie en argument à la méthode getItem(). Les données stockées sont renvoyées sous la forme d'une chaîne de caractères.


Suppression avec removeItem()
// Suppression de l'élément de session "identifiant"
sessionStorage.removeItem("identifiant");

// Suppression de l'élément de stockage local "derniere_visite"
localStorage.removeItem("derniere_visite");

Il ne faut pas hésiter à effacer les données devenues inutiles, l'espace total réservé étant de taille limitée. La méthode removeItem() est prévue à cet effet pour supprimer l'emplacement défini par la clé, ainsi que son stockage.


Suppression totale avec clear()
// Suppression complète de toutes les valeurs de session
sessionStorage.clear();
// Suppression complète de toutes les valeurs de stockage local
localStorage.clear();

Cette méthode n'affecte bien sûr que le stockage effectué à l'origine du document. Toutes les données mémorisées pour www.alsacreations.com, www.alsacreations.com:80, et www.alsacreations.com/html5/ sont concernées, mais pas celles des autres origines, par exemple un sous-domaine forum.alsacreations.com.

En matière de sécurité, il est recommandé de faire très attention à la portée de l'accès des données. Si celles-ci sont accessibles sur tout un domaine www.exemple.com, et que plusieurs développeurs différents ont accès à des sous-répertoires de ce domaine, par exemple dans le cadre d'un hébergement mutualisé sur www.exemple.com/le_site_de_roger/, et www.exemple/le_site_de_pierre/, ils peuvent lire mutuellement l'intégralité de leurs stockages respectifs. C'est pourquoi il vaut mieux éviter Web Storage dans ce cas de figure spécifique.

Un compteur de visites avec localStorage


Étant établie la persistance des données de localStorage au travers des visites successives, il serait tout à fait possible d'imaginer un compteur s'incrémentant à chaque consultation d'un document HTML.


Exemple complet



HTML5 : Web-Storage





Vous avez vu cette page
un nombre indéterminé de
fois.


Une précaution consiste à tester la présence de l'interface localStorage avec l'instruction typeof qui renvoie ?undefined' si le navigateur ne la comprend pas.

À l'aide de ces quelques fonctions de base, les possibilités sont infinies. Veillez cependant à en faire bon usage; si les ordinateurs de bureau actuels disposent d'une marge de stockage confortable, ce n'est pas nécessairement le cas de tous les périphériques mobiles.



Surveiller le dépassement de quota de stockage HTML5


L'espace alloué n'est malheureusement pas infini. Au moment de la rédaction de ce chapitre, deux pans de Web Storage demeurent flous et implémentés de façons différentes dans les navigateurs :

 la gestion des exceptions, c'est-à-dire la connaissance des erreurs potentielles lorsqu'une opération n'a pu être menée à bien,
 et la connaissance de l'espace restant.
Pour les implémentations complètes, une exception de type QUOTA_EXCEEDED_ERR est déclenchée si une tentative (infructueuse) d'écriture dépasse la limite. Placer les instructions dans un bloc try/catch JavaScript permet d'effectuer un essai de stockage, et d'attraper l'exception le cas échéant.


Détection du dépassement de quota
try {
  localStorage.setItem("data",
"0100000101101100011011000010000001111001011011110111010101110010001000
00011000100110000101110011011001010010000001100001011100100110010100100
00001100010011001010110110001101111011011100110011100100000011101000110
1111001000000111010101110011");
} catch(exception) {
  if(exception == QUOTA_EXCEEDED_ERR) {
    alert('Limite de stockage atteinte');
  }
}

Dans ce cas, la donnée n'est pas sauvegardée, et il faut faire de la place avant d'effectuer une nouvelle tentative.

Un soupçon de JSON



Il faut bien garder à l'esprit que tous les échanges concernent des chaînes de texte. C'est pourquoi l'exemple précédent doit faire appel à la fonction JavaScript parseInt() pour convertir les données stockées sous forme de caractères en nombre entier.

Toute variable étant au préalable convertie en texte grâce à sa méthode toString, la tentative de stockage et de lecture d'un objet JavaScript "commun" produira le résultat d'une simple conversion de cet objet en texte : "[object Object]". Pour passer outre, il faut employer le format JSON (JavaScript Object Notation), dont tous les navigateurs à la page sont équipés nativement. Ce dernier linéarise en une seule chaîne toutes les propriétés de l'objet.
Ce format est très courant dans la conception d'appels Ajax, notamment à l'aide de jQuery.

En savoir plus



RESSOURCE Spécification Web Storage par le W3C et WhatWG
 http://www.w3.org/TR/webstorage/
 http://dev.w3.org/html5/webstorage/
 http://www.whatwg.org/specs/web-apps/current-work/complete/webstorage.html
Pourquoi Web Storage ne figure pas directement dans la spécification HTML 5 ?
 http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-January/030110.html

Ces bonnes feuilles sont tirées de l'ouvrage "HTML 5 : Une référence pour le développeur web" écrit par Rodolphe Rimelé, et publié aux éditions Eyrolles. 













Aucun commentaire:

Enregistrer un commentaire