Stockage du navigateur pour les applications HTML5

Pendant des années, l’un des principaux avantages de l’écriture d’applications de bureau a été la facilité d’accès au stockage local sur la machine cliente. Les développeurs Web ont longtemps été incapables de stocker et d'extraire des données de la machine du client, mais il semble que cela puisse bientôt changer. Vous pourriez même penser qu'il l'a déjà fait après avoir lu cet article. Oui, je vais discuter des origines de la persistance des données sur la machine des clients, puis vous présenter le standard de stockage Web..

La plupart des développeurs Web savent que le seul type de stockage local auquel on peut s'attendre d'un navigateur Web se présente sous la forme de cookies. Eh bien, pas tout à fait. Le désir de stocker des données sur la machine cliente n’est pas un nouveau concept et n’a pas été conçu lors de la création de spécifications HTML5. Ce qui est encore plus surprenant, c’est qu’une implémentation fonctionnelle a été développée par Microsoft dans le cadre du jeu de fonctionnalités IE6. Ils l'ont appelé données d'utilisateur De plus, il garantissait au moins 640 Ko d'espace local par domaine, en fonction des règles de sécurité IE définies par l'utilisateur. Cela peut sembler être très peu d'espace par rapport à la norme actuelle, mais lorsque nous comparons cet espace à l'espace maximum de 4 Ko que nous offrent les cookies, l'amélioration est appréciable..

Quel est le problème avec les cookies?

Un certain nombre de choses. Le principal problème des cookies est qu’ils sont échangés entre le navigateur et le serveur avec chaque requête HTTP. Ce n'est pas un comportement souhaitable, car le plus souvent, les développeurs ne souhaitent pas transmettre de données locales au serveur plus d'une fois, voire jamais. Les cookies ne donnent pas le choix au développeur.

Comme nous l'avons dit précédemment, les cookies ne peuvent stocker que 4 Ko de données. Ce n'est pas beaucoup de données, néanmoins 4 Ko est assez de données pour ralentir sensiblement les requêtes de page.

De plus, les cookies sont échangés en clair entre le client et le serveur. Par conséquent, le seul moyen de les protéger consiste à chiffrer les données lors de la communication avec le serveur principal via SSL (Secure Socket Layer). Cependant, la plupart des sites Web sur Internet n'utilisent pas SSL, ce qui laisse le stockage ouvert aux oreilles indiscrètes..

Il y a d'autres problèmes qui rendent les cookies moins utiles. Dans l’idéal, les développeurs souhaitent pouvoir conserver de grandes quantités de données sur la machine cliente et ne pas avoir à les transmettre au serveur encore et encore..

Quelles sont les solutions alternatives?

Jusqu'à présent, nous n'avons pas abordé de solutions de contournement non standard pour la persistance de données sur l'ordinateur client. Lorsque les développeurs Adobe (alors connus sous le nom de Macromedia) publiaient Flash Player 6, ils devaient également résoudre le même problème. En 2002, Flash Player 6 a introduit une nouvelle fonctionnalité appelée Objet partagé local ou plus communément appelée Cookies Flash d'introduire efficacement les mêmes fonctionnalités que les cookies HTTP standard dans les animations et les sites Flash. Un objet partagé local a permis aux développeurs de conserver jusqu'à 100 Ko de données par défaut sur la machine cliente..

La deuxième solution est la mise en œuvre par Google du stockage local dans le cadre du plugin Gears pour les navigateurs Web. Gears était (et je vous explique pourquoi j’utilise était en un instant) la combinaison de nombreuses fonctionnalités manquantes et utiles nécessaires au développement d’applications Internet riches (RIA). Le stockage local de Gears était basé sur la spécification Web SQL moins populaire qui exploitait SQLite. Vous avez bien compris, Gears a fourni aux développeurs une base de données SQL complète pour leur permettre de conserver une quantité illimitée de données sur la machine cliente..

Les développeurs d’AMASS (Ajax Massive Storage System) ont saisi cette opportunité pour développer une bibliothèque JavaScript tierce permettant aux sites HTML standard de tirer parti de la fonctionnalité Local Shared Object de Flash ou du plugin Gears afin de conserver les données sur le serveur. machine client. En outre, la bibliothèque JavaScript Dojo est capable de détecter la disponibilité des mécanismes de stockage local (par exemple, Google Gears, un objet partagé local, etc.) et fournit une interface unifiée pour la persistance des données sur différents navigateurs Web..

Revenons à la raison pour laquelle j'ai dit que Gears "restait" au lieu de "toujours": c'est parce que Google a récemment annoncé qu'il abandonnerait le développement du plugin Gears au profit de HTML5 et de la spécification Web Storage présentée dans ce tutoriel..

Spécifications HTML5 et Web Storage

Maintenant que la leçon d'histoire est terminée, nous allons en apprendre davantage sur le stockage Web et explorer un peu de code pour mieux le comprendre. Le moyen le plus simple de décrire le stockage Web consiste à conserver des données sur l'ordinateur client sous la forme d'une clé pour une valeur. Ceci est très similaire à la manière dont les tableaux associatifs sont utilisés:

 "La clé": "La valeur"

Le stockage local est conçu pour être pris en charge de manière native par les navigateurs Web. Cela signifie plus de bibliothèques tierces et de jouer avec Flash. Étonnamment, le stockage Web a été l’une des spécifications les plus réussies en termes d’adoption par les navigateurs modernes. En fait, presque tous les navigateurs modernes prennent en charge le stockage Web, notamment:

  • Internet Explorer 8+
  • Firefox 3.5+
  • Safari 4+
  • Opera 10.5+
  • iPhone Safari
  • Navigateur Web Android

Si le stockage Web vise à fournir des fonctionnalités similaires aux cookies, il a été affiné pour ne porter aucun de leurs attributs négatifs. Par exemple, le stockage Web permet de conserver jusqu'à 5 Mo de données, ce qui représente une augmentation considérable de l'espace par rapport à la quantité de données pouvant être stockée dans un cookie. En outre, la persistance des données à l'aide du stockage Web n'entraînera pas l'envoi de ces données au serveur principal avec chaque demande de page. Cela augmente considérablement les performances. Selon la spécification de stockage Web, les navigateurs Web n'expirent que les données persistantes de la machine locale à la demande de l'utilisateur. Ils évitent toujours de supprimer des données lorsqu'un script pouvant accéder à ces données est en cours d'exécution..

Les navigateurs Web exposent le stockage Web via le stockage local objet en JavaScript. Un moyen simple de déterminer si un navigateur Web peut prendre en charge le stockage Web consiste à exécuter ce code JavaScript:

 var webStorageSupported = ('localStorage' dans la fenêtre) && window ['localStorage']! == null;

Selon les spécifications du W3C pour le stockage Web, le stockage local object implémente l'ensemble de méthodes et propriétés suivant à partir de l'interface de stockage. Examinons chacune de ces méthodes et propriétés pour déterminer ce qu'elles font et comment elles peuvent être utilisées:

 interface de stockage en lecture seule longueur; vide setItem (clé de chaîne, données d'objet); Objet getItem (clé de chaîne); vide removeItem (clé de chaîne); vide clair(); Chaîne clé (index long); ; 

le longueur la propriété est très utile. Il renverra le nombre de paires clé / valeur actuellement enregistrées sur le stockage local sous le domaine actuellement utilisé:

 alerte (localStorage.length);

Si aucune paire clé / valeur n'a précédemment été enregistrée dans la mémoire de stockage locale, le script ci-dessus affichera une fenêtre d'alerte avec le message "0", sinon le message correspondra au nombre de paires clé / valeur persistantes..

le setItem (clé, valeur) méthode enregistre simplement une nouvelle entrée sur la machine locale. Pour sauvegarder la clé prénom avec la valeur arman nous pourrions exécuter ce script:

 localStorage.setItem ('name', 'arman');

Pour assurer cette clé prénom a été vraiment sauvegardé dans le stockage local avec la valeur arman nous devons utiliser le getItem (clé) méthode. le obtenir l'article La méthode accepte simplement une clé et cherche dans la mémoire locale la clé correspondante, puis renvoie sa valeur..

 localStorage.setItem ('name', 'arman'); var value = localStorage.getItem ('name'); alerte (valeur);

Si vous exécutez le script ci-dessus, une fenêtre d’alerte contenant le mot arman s'affiche à l'écran, confirmant que nous avons correctement enregistré une nouvelle paire clé / valeur dans la mémoire de stockage locale. Depuis le stockage local objet se comporte comme les tableaux associatifs, nous pourrions simplifier le script ci-dessus pour qu'il ressemble à ceci et qu'il fonctionne toujours de la même manière:

 localStorage ['name'] = 'arman'; valeur var = localStorage ['name']; alerte (valeur);

Regardons le removeItem (clé) méthode. Cette méthode est conçue pour supprimer une paire clé / valeur précédemment enregistrée du stockage local. Si la clé n'existe pas, cette méthode ne fait simplement rien. L’exemple de code suivant illustre l’utilisation de la retirer l'objet méthode:

 localStorage.setItem ('name', 'arman'); localStorage.removeItem ('name'); var value = localStorage.getItem ('name'); alerte (valeur);

Lorsque le script ci-dessus est exécuté, vous devriez voir une fenêtre d’alerte avec la valeur nul dans la boîte d'alerte. En utilisant le prénom key, le script ci-dessus crée simplement une nouvelle paire clé / valeur et la supprime immédiatement du stockage local. Par la suite, une valeur NULL est renvoyée lors de l’accès au stockage local avec le même prénom clé.

Il y aura des occasions où il sera nécessaire de vider complètement le stockage local et de commencer avec une table rase. le clair() méthode est conçue exactement à cette fin. Cette méthode vide automatiquement toutes les paires clé / valeur précédemment enregistrées de la mémoire de stockage locale. S'il n'y a pas d'entrées, rien ne changera.

 localStorage.setItem ('name', 'arman'); localStorage.setItem ('name', 'smith'); localStorage.setItem ('name', 'frank'); alerte (localStorage.length); localStorage.clear (); alerte (localStorage.length);

Bien que le script ci-dessus crée trois nouvelles paires clé / valeur (comme en témoigne la première alerte), l'appel de la méthode clear () supprime toutes les entrées. Par la suite, la deuxième fenêtre d’alerte affichera un message "0".

La dernière méthode que nous devons examiner est la clé (index) méthode. Cette méthode récupérera le nom d'une clé en fonction du paramètre index. stockage local maintient une liste basée sur 0 de toutes les entrées en son sein. Par conséquent, pour accéder à la première clé à partir du stockage local, nous devons utiliser 0 comme index, comme illustré dans ce script:

 localStorage.clear (); localStorage.setItem ('age', 5); alerte (localStorage.key (0));

Lorsque le script ci-dessus est exécuté, une fenêtre d’alerte contenant le message "age" doit apparaître. Notez que dans l'exemple ci-dessus, la première ligne de code efface le stockage local. Ceci est pour nous assurer de commencer par une table rase. Une autre application utile de la clé() méthode est en conjonction avec le longueur propriété. Par exemple, pour obtenir toutes les paires clé / valeur du stockage local sans connaître les clés à l'avance, nous pourrions écrire un script du type suivant:

 localStorage.clear (); localStorage.setItem ("titre", "M."); localStorage.setItem ("nom complet", "Aaron Darwin"); localStorage.setItem ("age", 17 ans); localStorage.setItem ("height", 182,5); pour (var i = 0; i < localStorage.length; i++)  var keyName = localStorage.key(i); var value = localStorage.getItem(keyName); alert(keyName + " = " + value); 

Dans le script ci-dessus, notre code efface d'abord puis ajoute quatre nouvelles paires clé / valeur à la mémoire de stockage locale. Ensuite, il utilise le longueur propriété dans un Pour boucle pour élaborer la clé pour chaque paire clé / valeur. A chaque itération de la boucle, la clé est affectée au keyName variable qui est ensuite passée à la obtenir l'article() méthode pour récupérer sa valeur.

Les subtilités

Lors de l’accès aux données à l’aide d’une clé qui n’existe pas dans le stockage local, au lieu d’une exception, un nul la valeur est toujours retournée. Cela rend difficile de savoir si la valeur de la clé est nul ou la clé n'existe tout simplement pas dans le stockage local.

Le deuxième sujet à aborder est le setItem (clé, valeur) méthode. Nous savons que nous pouvons transmettre tout type de valeur à la setItem () méthode pour la valeur paramètre, mais ce n'est pas tout à fait vrai. En JavaScript, nous pouvons créer Image objets. Cependant, l’implémentation actuelle du stockage Web autorise uniquement les types primitifs persistants tels que Chaîne, Booléen, Entier et Flotte les types. Par conséquent, nous pouvons nous attendre à ce que le script suivant lève une exception et se bloque:

 var imageObject = new Image ("http://www.google.com/logo.gif"); localStorage.setItem ("image", imageObject);

De plus, même si nous pouvons économiser Booléen, Entier et Flotte types, la représentation sous-jacente de ces types retombe sur le Chaîne type. Cela signifie quel que soit le type de valeur transmis au setItem () méthode, la obtenir l'article() La méthode retournera toujours une valeur de type String. Regardons un exemple de script:

 var integerVariable = 34; localStorage.setItem ("age", integerVariable); var newVariable = localStorage.getItem ("age"); alert (typeof (newVariable) == "numéro");

Dans le script ci-dessus, finalement, la valeur de integerVariable est enregistré en tant que chaîne. Par conséquent, lorsque nous inspectons le type de newVariable après avoir extrait sa valeur du stockage local, ce n'est plus un type Integer et, par conséquent, l'instruction de comparaison est évaluée à false. Dans de telles situations, nous devons utiliser le pratique parseInt (String) et parseFloat (String) fonctions pour la conversion. Il n'y a AUCUNE fonction à analyser Booléen type de données donc nous devons simplement comparer la valeur extraite avec des chaînes "true" ou "false".

Enfin, pour obtenir la déclaration de comparaison dans le script ci-dessus à évaluer pour vrai, nous devons modifier notre code pour utiliser la fonction parseInt () comme indiqué dans le script suivant:

 var integerVariable = 34; localStorage.setItem ("age", integerVariable); var newVariable = parseInt (localStorage.getItem ("age")); alert (typeof (newVariable) == "numéro");

Maintenant, lorsque le script ci-dessus est exécuté, le type de la valeur stockée dans le newVariable sera Entier. Par la suite, la déclaration de comparaison évaluera à vrai.

Lorsque les données persistantes atteignent le quota de 5 Mo, les navigateurs Web ne permettent pas de demander plus d'espace dans la mémoire de stockage locale. Ils jettent à la place QUOTA_EXCEEDED_ERR exception pour signaler au script qu'il n'y a plus d'espace. Le moyen le plus simple de gérer cette exception consiste à intercepter l'exception et à informer l'utilisateur du problème..

Alternativement, lors de la capture de l'exception, le script peut supprimer certaines entrées clé / valeur du stockage local pour libérer de l'espace pour de nouvelles paires..

Enfin, lorsque le document est demandé directement à partir du disque et non d'un serveur Web, la mémoire de stockage locale est effacée chaque fois que vous naviguez en dehors de la page..

Événements de stockage Web

Web Storage Standard permet aux scripts d'être notifiés lorsque d'autres parties du code ajoutent, mettent à jour ou suppriment des entrées du stockage local. Ainsi, chaque fois que quelque chose change dans le stockage local, un Événement de stockage va tirer. Cependant, dans le cas de la suppression d'une entrée à l'aide d'une clé non existante, aucun événement ne sera déclenché. En effet, rien ne changera dans le stockage local. Malheureusement, mes tests ont prouvé qu’à l’heure actuelle, les navigateurs Webkit (tels que Safari et Chrome) ne sont pas activés. Événements de stockage comme décrit par la spécification de stockage Web. Les navigateurs Internet Explorer, Firefox et Opera se comportent comme prévu.

Un événement de stockage local ne peut pas être annulé. Son seul but est de notifier au code utilisateur un changement survenu dans la mémoire de stockage locale..

Le script suivant vous montre comment écouter les modifications apportées au stockage local en enregistrant un gestionnaire d'événements qui sera appelé à chaque fois Événement de stockage est viré:

 if (window.addEventListener) window.addEventListener ("storage", handleStorageChange, false);  else window.attachEvent ("onstorage", handleStorageChange);  function handleStorageChange (event) alert ("Quelque chose a été modifié dans le stockage local"); 

Comme aucune version d'Internet Explorer (à l'exception de la version 9 de l'aperçu public) ne prend en charge le système de gestion d'événements DOM niveau 2, le attacheEvent () méthode doit être utilisée pour enregistrer les gestionnaires d'événements.

le un événement Cet argument est utile car il contient des informations sur les modifications apportées au stockage local. Il adhère à la StorageEvent interface:

 interface StorageEvent: Event readonly String clé; objet lecture seule oldValue; objet en lecture seule nouvelle valeur; en lecture seule url; ; 

le clé propriété identifie la paire clé / valeur qui a été modifiée. le oldValue et le nouvelle valeur les propriétés se comportent comme leur nom l'indique. C'est-à-dire qu'ils contiennent respectivement la valeur précédente et la nouvelle valeur pour la clé..

Finalement, le url property contient l'adresse du document pour lequel le stockage local vient d'être modifié. Cependant, en raison de plusieurs itérations d’implémentation de la spécification de stockage Web, dans certains navigateurs Web, la url la propriété peut être implémentée comme uri. Par conséquent, il est préférable de vérifier d'abord le url la propriété et ensuite uri au cas où le url la propriété est indéfinie.

Démo

Après avoir lu beaucoup de choses, j’aime habituellement voir un exemple avant de tout croire. Tout comme moi, je suis sûr que beaucoup d’entre vous aimeraient également voir un exemple concret. Ce n'est pas un problème, car j'ai préparé un petit script qui montre simplement l'utilisation de la norme de stockage Web dans une application opérationnelle..

Il est conçu pour pouvoir également être testé avec iPhone Safari et le navigateur Web Android. L'idée est de laisser le navigateur se souvenir des boîtes qui ont été ouvertes avant d'utiliser le stockage local. Je vous laisse avec ce code pour jouer avec:

         

Démo de stockage Web

Cette page a été conçue pour démontrer simplement l'utilisation du stockage Web dans les navigateurs modernes. Dans cet exemple, les cases sur lesquelles vous n'avez pas encore cliqué restent noires. Une fois que vous cliquez sur une boîte noire, sa couleur réelle sera révélée. Le navigateur se souviendra cependant des zones sur lesquelles vous avez cliqué, même lorsque vous quittez cette page. Allez, essayez.