IndexedDB est un moyen pour permettre le stockage de données dans le navigateur d'un utilisateur, de manière persistante. Ses fonctions de recherche avancées permettent de créer des applications qui fonctionnent tant connectées que déconnectées. IndexedDB est utile pour créer des applications qui stockent une grande quantité de données (par exemple : un catalogue de DVDs dans une bibliothèque) et des applications qui n'ont pas forcément besoin d'une connectivité Internet continue (par exemple : des clients de messagerie électronique, des listes de tâches, des bloc-notes).

À propos de ce document

Ce document introduit les concepts et les termes essentiels d'IndexedDB. Vous aurez une vue d'ensemble et vous comprendrez les concepts-clés.

Vous pourrez trouver ici :

Vue d'ensemble d'IndexedDB

IndexedDB vous permet de stocker et récupérer des objets qui sont indexés avec une "clé". Tous les changements que vous faites dans la base de données sont forcément transactionnels. Comme la plupart des solutions de stockage du web, IndexedDB respecte la politique de sécurité utilisant l'origne (same-origin policy). Ainsi, vous pouvez accéder aux données stockées d'un domaine, alors que vous ne pouvez pas accéder aux données de domaines différents.

UndexedDB est une API asynchrone qui peut être utilisée dans la plupart des contextes, Web Workers inclus. Elle comportait également une version synchrone prévue pour être utilisée dans des Web Workers. mais cette option a été retirée de la spécification en raison du manque d'intérêt de la communauté Web.

IndexedDB est une alternative à l'API WebSQL Database, qui a été dépréciée par le W3C le 18 novembre 2010. Alors que ces APIs sont toutes deux des solutions de stockage, elles n'offrent pas les mêmes fonctionnalités. WebSQL Database est un système d'accès à une base de données relationnelle alors qu'IndexedDB est un système de table indexée. 

Les grands concepts

Si vous avez l'habitude de travailler avec d'autres types de bases de données, vous pourrez être désorienté par l'utlisation d'IndexedDB. Mais il suffit de garder les concepts importants suivants en tête :

  • Les bases de données IndexedDB stockent des paires clé-valeur. Les valeurs peuvent êtres des objets structurés, et les clés peuvent être des propriétés de ces objets. Vous pouvez créer des index à partir de n'importe quelle propriété des objets, pour faciliter la recherche et l'énumération triée. Les clés peuvent être des objets binaires.
  • IndexedDB est construit autour d'un modèle de base de données transactionnelle. Tout ce que vous faites avec IndexedDB se passe dans le contexte d'une transaction. L'API IndexedDB fournit beaucoup d'objets qui représentent des index, des tables, des curseurs, etc, mais chacun de ces objets est forcément relié à une transaction donnée. Il n'est pas possible d'exécuter de commandes ou d'ouvrir des curseurs en dehors d'une transaction. Les transactions ont une durée de vie bien définie, donc essayez d'utiliser une transaction après avoir terminé le traitement des exceptions. De plus, les transactions s'engagent automatiquement, elles ne peuvent être lancées manuellement.
    Ce modèle basé sur des transactions est vraiment utile : rendez-vous compte qu'un utilisateur peut ouvrir deux instances de la même application web dans deux onglets différents en même temps. Si on n'utilisait pas d'opérations transactionnelles, une instance pourrait écraser les modifications de l'autre, et vice versa. Si vous n'êtes pas à l'aise avec la notion de transaction dans une base de données, vous pouvez consulter l'article Wikipedia sur les transactions. Vous pouvez aussi voir plus loin la partie transaction dans la section des définitions.
  • L'API IndexedDB est principalement asynchrone. L'API ne vous donne pas les données en retournant des valeurs. Au contraire, vous devez utiliser une fonction de rappel ("callback"). Vous ne stockez pas une valeur dans la base de données, ou vous ne récupérez pas une valeur de la base de manière synchrone, mais vous demandez qu'une opération de base de données soit exécutée. Un événement DOM est envoyé lorsque l'opération est terminée, et le type d'événement vous permet de savoir si l'opération a réussi ou échoué. Cela peut sembler un peu compliqué au premier abord, mais après tout, ce n'est pas si différent du fonctionnement de XMLHttpRequest.
  • IndexedDB utilise de nombreuses requêtes. Les requêtes sont des objets qui reçoivent les événements DOM de succès ou d'échec mentionnés précédemment. Elles ont des propriétés onsuccess et onerror, et vous pouvez appeler addEventListener() et removeEventListener() sur ces objets. Elles ont aussi les propriétés readyState, result, et errorCode qui vous donnent l'état d'une requête. La propriété result est plutôt magique car elle peut correspondre à beaucoup de choses différentes, en fonction de la manière dont la requête a été créée (par exemple, une instance de IDBCursor, ou la clé de la valeur que vous venez d'insérer dans la base de données.)
  • IndexedDB utilise les évènements DOM pour vous informer quand les résultats sont disponibles. Les évènements DOM ont toujours une  propriété de type (dans IndexedDB, sont préférables "success" (succès) ou "error" (erreur)). Les évènements DOM ont aussi une propriété target (cible) qui dit vers où l'évènement est dirigé. Dans la plupart des cas, la target d'un évènement est l'objet IDBRequest qui a été généré à la suite d'une opération de base de données . Les événements "success" ne se propagent pas et ne peuvent être annulés . Les évènements "Error", se propagent et peuvent être annulés. C'est très important, lors d'un événement d'erreur, les transactions annulent au fur et à mesure qu'elles s'exécutent, à moins qu'il ne soit annulé .
  • IndexedDB est orienté objet. IndexedDB n'est pas une base de données relationnelle, avec des tables, des colonnes et des lignes. Cette différence importante et fondamentale change votre manière de concevoir et construire vos applications.
    Dans un espace de stockage de données relationel habituel, on aurait un tableau qui permet de stocker un ensemble de lignes de données, et de colonnes de types nommés de donnée. Avec IndexedDB, au contraire, vous créez un objet de stockage pour un type de données, et les objets JavaScript persistent simplement dans cet espace. Chaque objet de stockage peut utiliser un ensemble d'index qui rendent efficaces la recherche et l'itération. Si les systèmes de base de données orientée objet ne vous sont pas familiers, vous pouvez aller lire l'article Wikipedia sur les bases de données orientées objet.
  • IndexedDB n'utilise pas le langage Structured Query Language (SQL). Il utilise des requêtes sur un index pour obtenir un curseur, que l'on utilise ensuite pour parcourir l'ensemble des résultats. Si vous ne connaissez pas bien les systèmes NoSQL, vous pouvez consulter l'article Wikipedia sur NoSQL.
  • IndexedDB adhère au principe de same-origin policy (politique de même origine). Une origine est le domaine, le protocole d'application et le port URL du document où le script est exécuté. Chaque origine a son propre ensemble de bases de données associées . Chaque base de données a un nom qui l'identifie dans une origine.
    La limite de sécurité d'IndexedDB empêche les applications d'accèder à des données d'origine différente. Par exemple, alors qu'une application ou une page http://www.example.com/app/ peut récupérer des données de http://www.example.com/dir/, parce qu'elles ont la même origine, elle ne peut pas récupérer les données de http://www.example.com:8080/dir/ (port différent) ni de https://www.example.com/dir/ (protocole différent), parce que leurs origines sont différentes.

Définitions

Cette section définit et explique les termes utilisés dans l'API IndexedDB.

Database (base de données)

database (base de données)
Un référentiel d'informations, comprenant généralement un ou plusieurs objets de stockage. Chaque base de données doit avoir les éléments suivants :
  • Name . (nom) Il identifie la base de données dans une origine spécifique et reste constant tout au long de la durée de sa vie. Le nom peut être n'importe quelle valeur de chaîne de caractères (y compris une chaîne vide).
  • Current version (version actuelle). Lors de la création de la base de données, sa version est le nombre entier 1. Chaque base de données ne peut avoir qu'une seule version à un moment donné .
durable
Dans Firefox, IndexedDB était durable, ce qui signifie que dans une transaction readwrite (lecture/écriture) IDBTransaction.on complet était déclenché uniquement lorsque toutes les données étaient garanties, avant d'être écrites sur le disque.
À partir de Firefox 40, les transactions IndexedDB ont des garanties de durabilité relachées pour augmenter les performances (voir bug 1112702) ; comportement identique à celui des autres navigateurs qui mettent en oeuvre IndexedDB. Dans ce cas, l'événement complete est déclenché après la réception par le système d'exploitation de la commande d'écriture, mais potentiellement avant l'écriture effective de ces données sur le disque. L'événement peut donc être livré plus rapidement qu'avant, mais il existe un petit risque que la transaction entière soit perdue si le système d'exploitation l'écrase ou s'il y a une perte de puissance du système avant l'écriture sur le disque. Étant donné que ces événements catastrophiques sont rares, la plupart des consommateurs ne devraient pas nécessairement s'en préoccuper davantage.

Note : Dans Firefox, si vous souhaitez être sûr de la durabilité pour une raison ou une autre (par exemple, vous stockez des données critiques qui ne peuvent pas être recalculées plus tard), vous pouvez forcer une transaction d'écriture sur le disque avant la délivrance de l'évènement complete  par la création d'une transaction utilisant le mode expérimental (non standard) readwriteflush  (voir IDBDatabase.transaction).  Ceci est actuellement expérimental et ne peut être utilisé que si la préférence dom.indexedDB.experimental est renseignée avec " true " (vrai) dans about:config.

 
object store (objet de stockage)

Le mécanisme avec lequel les données sont stockées dans la base de données. L'objet de stockage maintient constamment ses enregistrements, lesquels sont des paires  "key-value" (clé-valeur). Les enregistrements dans l'objet de stockage sont triés dans l'ordre ascendant des "keys" (clés).

Chaque objet de stockage doit avoir un nom qui est unique dans la base de données. Il peut éventuellement avoir un key generator (générateur de clé) et un key path (chemin de clé). S'il a un "key path", il utilise in-line keys (clés en ligne) ; sinon, il utilise out-of-line keys (clé hors ligne).

Pour la documentation de référence sur les objets de stockage, voir IDBObjectStore ou IDBObjectStoreSync.

version
À la première création de la base de données, sa version est le nombre entier 1. Chaque base de données possède une seule version à un moment donné ; il ne peut pas exister plusieurs versions dans le même temps. La seule façon de changer la version est de l'ouvrir avec une version plus haute. Ceci démarre une transaction VERSION_CHANGE et lance un évènement upgradeneeded. Le seul endroit où le schéma de la base de données peut être mis à jour est à l'intérieur du gestionnaire de cet événement.
Note : Cette définition décrit les spécifications les plus récentes, qui ne sont implémentées que dans des navigateurs à jour. Les anciens navigateurs ont implémenté la méthode IDBDatabase.setVersion() maintenant obsolète et supprimée.
database connection (connexion de la base de données)
Une opération créée en ouvrant une database (base de données). Une base de données peut avoir plusieurs connexions en même temps.
transaction

Un ensemble atomique d'accès aux données et d'opérations de modification des données sur une base de données particulière. C'est la façon dont vous interagissez avec les données dans une base. En fait, toute lecture ou changement dans la base de données doit se produire dans une transaction.

Une connexion à la base de données peut avoir plusieurs transactions actives associées à la fois, pourvu que les transactions d'écriture n'aient pas de chevauchement scopes. La portée (scope) des transactions, qui est définie lors de la création, détermine l'objet avec lequel la transaction peut interagir, et reste constante pour la durée de vie de la transaction. Ainsi, par exemple, si une connexion à la base de données a déjà une transaction d'écriture avec une portée qui couvre simplement l'objet de stockage flyingMonkey , vous pouvez commencer une seconde transaction avec une portée sur les objets de stockage unicornCentaur et unicornPegasus. En ce qui concerne les transactions de lecture, vous pouvez en avoir plusieurs - même avec chevauchements.

Les transactions doivent être de courte durée, pour que le navigateur puisse mettre fin à une transaction trop longue, afin de libérer des ressources de stockage verrouillées par cette dernière. Vous pouvez annuler la transaction, ce qui modifie les changements apportés à la base de données dans la transaction. Et vous n'avez même pas à attendre que la transaction commence ou soit active pour l'annuler.

Les trois modes de transaction sont : " readwrite " (lecture/écriture), " readonly " (lecture seule), et " versionchange " (changement de version). La seule manière de créer et supprimer les objets de stockage et les index est d'utiliser une transaction versionchange . Pour en apprendre plus sur les types de transactions, voir l'article de référence pour IndexedDB.

Parce que tout se passe au sein d'une transaction, c'est un concept très important dans IndexedDB. Pour en savoir plus sur les transactions, en particulier sur la façon dont elles se rapportent aux versions, voir IDBTransaction, qui a également une documentation de référence . Pour la documentation sur l'API synchrone, voir IDBTransactionSync.

request (requêtes)
L'opération par laquelle la lecture et l'écriture sur une base de données est effectuée. Chaque requête représente une opération de lecture ou d'écriture.
index

Un index est un objet de stockage spécialisé pour rechercher des enregistrements dans un autre objet de stockage appelé " referenced object store"  (objet de stockage référencé). L'index est un stockage persistant de key-value (clé-valeur)  dans lequel la partie "value" des enregistrements contient la partie "key" d'un enregistrement de l'objet de stockage référencé. Les enregistrements dans un index sont automatiquement remplis chaque fois que ceux de l'objet référencé sont insérés, mis à jour ou supprimés. Chaque enregistrement d'un index ne peut indiquer qu'un seul enregistrement dans son objet référencé, mais plusieurs index peuvent référencer le même objet. Lorsque l'objet référencé change, tous les index qui s'y réfèrent sont mis à jour automatiquement.

Vous pouvez également rechercher des enregistrements dans un objet de stockage en utilisant la clé.

Pour en apprendre plus sur l'utilisation des index, voir Using IndexedDB. Pour la documentation de référence sur l'index, voir IDBKeyRange.

Key and value (clé et valeur)

key (clé)

Une valeur de données par laquelle les valeurs stockées sont organisées et récupérées dans l'objet de stockage . Celui-ci peut obtenir la clé de l'une des trois sources : un générateur de clés, un chemin de clé et une valeur explicitement spécifiée. La clé doit être d'un type de données qui a un nombre supérieur au précédent. Chaque enregistrement doit avoir une clé unique dans l'objet de stockage, de sorte que celui-ci ne peut comporter plusieurs enregistrements avec la même clé.

Une clé peut être de l'un des types suivants : string (chaîne de caractères), date, float (flottante), binary blob (blob binaire) et array (tableau). Pour les tableaux, la valeur de la clé peut être comprise entre vide et l'infini. Et vous pouvez inclure un tableau dans un tableau.

Vous pouvez également rechercher des enregistrements dans un objet de stockage en utilisant l'index.

key generator (générateur de clé)
Un mécanisme pour produire de nouvelles clés dans une séquence ordonnée. Si un objet de stockage n'a pas de générateur de clé, l'application doit fournir les clés des enregistrements stockés. Les générateurs ne sont pas partagés entre les objets de stockage. Il s'agit d'un détail concernant les navigateurs, car dans le développement web, vous ne créez pas réellement ou ne gérez pas les accès aux générateurs de clés.
in-line key (clé en ligne)
Une clé qui est stockée comme partie d'une valeur de stockage. Elle est trouvée en utilisant "key path" (chemin de clé). Une clé en ligne peut être créée par un générateur. Une fois la clé générée, elle peut être stockée dans la valeur utilisant le "key path" ou être utilisée comme clé.
out-of-line key (clé hors ligne)
Une clé stockée séparément de la valeur stockée.
key path (chemin de clé)
Définit où le navigateur doit extraire la clé d'une valeur dans l'objet de stockage ou l'index. Un chemin de clé valide peut inclure l'un des éléments suivants : une chaîne vide, un identifiant JavaScript ou plusieurs identifiants JavaScript séparés par des périodes, ou un tableau contenant ces éléments. Il ne peut pas inclure d'espaces.
value (valeur)

Chaque enregistrement a une valeur, qui peut inclure tout ce qui peut être exprimé en JavaScript, y compris : boolean (bouléen), number (nombre), string (chaîne de caractères), date, object (objet), array (tableau), regexp, undefined (indéfini), and null (nul).

Quand un objet ou un tableau est stocké, les propriétés et valeurs dans cet objet ou ce tableau peuvent aussi être toute valeur valide.

Blobs et fichiers peuvent être stockés, voir specification .

Intervalle et portée

scope (portée ou étendue)
L'ensemble des objets de stockage et index auxquels s'applique une transaction. Les portées des transactions en lecture seule peuvent se chevaucher et s'exécuter en même temps. Par contre, les portées des transactions d'écriture ne peuvent pas se chevaucher. Vous pouvez toujours démarrer plusieurs transactions avec la même portée en même temps, mais elles entrent dans une file d'attente et s'exécutent l'une après l'autre.
cursor (curseur)
Un mécanisme pour l'itération de plusieurs enregistrements avec une "key range" (intervalle de clés). Le curseur possède une source qui indique quel index ou objet stocké est itéré. Il a une position dans l'intervalle et se déplace dans une direction qui augmente ou diminue dans l'ordre des clés d'enregistrement. Pour la documentation de référence sur les curseurs, voir IDBCursor ou IDBCursorSync.
key range (intervalle de clés)

Un intervalle continu sur un type de données utilisé pour les clés. Les enregistrements peuvent être récupérés à partir des objets de stockage et des index à l'aide de touches ou d'un intervalle de clés. Vous pouvez limiter ou filtrer l'intervalle en utilisant les limites inférieures et supérieures. Par exemple, vous pouvez itérer sur toutes les valeurs d'une clé entre x et y.

Pour la documentation de référence sur "key range", voir IDBKeyRange.

Limitations

IndexedDB est conçu pour couvrir la plupart des cas qui nécessitent un stockage côté client. Cependant, il n'est pas adapté pour quelques cas comme les suivants :

  • Tri par classement international . Toutes les langues ne trient pas les chaînes de la même manière, de sorte que le classement ne peut être internationalisé. Bien que la base de données ne puisse pas stocker des données dans un ordre spécifiquement international, vous pouvez trier les données que vous avez déjà lues sur votre base de données. Notez, cependant, que le locale-aware sorting a été autorisée avec un indicateur expérimental activé (actuellement pour Firefox uniquement) depuis Firefox 43.
  • Synchronisation . L'API n'est pas conçue pour prendre en charge la synchronisation avec une base de données côté serveur. Vous devez écrire un code qui synchronise une base de données indexedDB côté client avec une base de données côté serveur.
  • Recherche de texte intégral . L'API n'a pas d'équivalent à l'opérateur LIKE en SQL.

En outre, sachez que les navigateurs peuvent effacer la base de données, comme dans les conditions suivantes :

  • L'utilisateur demande un effacement. De nombreux navigateurs ont des paramètres qui permettent aux utilisateurs d'effacer toutes les données stockées pour un site Web donné, y compris les cookies, les signets, les mots de passe stockés et les données IndexedDB.
  • Le navigateur est en mode de navigation privée. Certains navigateurs ont des modes "navigation privée" (Firefox) ou "incognito" (Chrome). À la fin de la session, le navigateur efface la base de données.
  • La limite de disque ou de quota a été atteinte.
  • Les données sont corrompues.
  • Un changement incompatible est apporté à la fonctionnalité.

Les circonstances exactes et les capacités du navigateur changent au fil du temps, mais la philosophie générale des fournisseurs de navigateurs est de faire les efforts nécessaires pour conserver les données lorsque c'est possible.

Étape suivante

Avec ces grands concepts dans nos poches, nous pouvons obtenir des choses plus concrètes. Pour un tutoriel sur l'utilisation de l'API, voir Using IndexedDB.

Voir aussi

Spécification

Référence

Tutoriels

Article connexe

Étiquettes et contributeurs liés au document

Étiquettes : 
 Contributeurs à cette page : loella16, Alpha, SphinxKnight, teoli, julienw
 Dernière mise à jour par : loella16,