OWF12/HTML 5 local storage , olivier thomas, cto at webtyss
-
Upload
open-world-forum -
Category
Documents
-
view
751 -
download
3
description
Transcript of OWF12/HTML 5 local storage , olivier thomas, cto at webtyss
Stockage local dans les navigateurs
Pourquoi du stockage local ?
● Des WebApps, pas de "simples" sites Web...● Proposer une expérience utilisateur identique, avec ou sans connexion
● Indispensable pour rivaliser avec les applications natives
● La gestion du offline, primordiale pour les applis mobiles
Les différents types de stockage
● Stockage local de données utilisateurs● Cookies● Local Storage (également appelé Web Storage, HTML 5 Storage ou
Dom Storage)● Web SQL Database (WebDB)● IndexedDB
● Caching● Stockage de pages et ressources associées
Les challenges du stockage local des données
● De la capacité !
● De la persistence, au-delà des refresh de page!
● Une manipulation des données à la fois puissante et souple pour l'utilisateur
● Laisser à l'utilisateur le libre choix sur les données à échanger avec le serveur
Cookies
● Stockage de petites quantités d’informations sous un format clé/valeur
● Cookies de sessions vs Cookies persistents● Utilisation de l’attribut “expires”
● Max 4KB de données par cookie et 20 cookies par domaine
● Les cookies transitent systématiquement entre le navigateur et le site --> overhead
Manipulation des cookies
● Option 1 : Manipulation des cookies au niveau de l’enveloppe HTTP
● Poser un cookie
Set-Cookie : NOM=VALEUR; domain=NOM_DE_DOMAINE; expires=DATE
● Option 2 : Manipulation des cookies au niveau javascript● Utilsation de l’objet document.cookie
● var expire = new Date();var unAn = expire.getTime() + (365*24*60*60*1000);expire.setTime(unAN);document.cookie = "JDNCookie=Test; expires=" + expire.toGMTString();
Implémentation "Local Storage"
● Stockage de données au format "Clé / Valeur"
● Les avantages :
● Un stockage réellement persistent
● Une API très simple à utiliser
● Mécanisme d'événements pour intercepter les modifications effectuées sur l'espace de stockage
Local Storage
● Les limitations
● Plus grande capacité de stockage que les cookies mais limitation à 5MB par domaine
● Stockage de données de n'importe quel type mais sous forme de chaînes --> Sérialisation et Désérialisation nécessaires !
● Un mode de stockage peu propice aux structures de données complexes
Local Storage - Code
● L'accès au stockage local s'effectue par l'objet window.localStorage
● Des méthodes simples de manipulation de données● clear()● getItem()
● value = window.localStorage.getItem(key)● setItem()
● window.localStorage.setItem(key, value)● removeItem● Key
Local Storage - itération
Disponibilité d'une fonction 'length'
for (var i = 0; i < localStorage.length; i++) { var key = localStorage.key(i); var value = localStorage.getItem(key);}
Local Storage - Evénements
Ajout d'un listener sur l'événement 'storage'
window.addEventListener("storage", function(event) { var key = event.key; var newValue = event.newValue; var oldValue = event.oldValue; var url = event.url; var storageArea = event.storageArea; // handle the event});
Local Storage : détecter si la fonctionnalité est supportée
Manuellement ou via l'utilisation de script spécialisé (ex: Modernizr)
if (Modernizr.localstorage) { // window.localStorage is available!} else { // no native support for local storage :(}
Local Storage - Navigateurs supportés
● Local Storage est aujourd'hui supporté par l'ensemble des navigateurs fixes et mobiles.
Web SQL Database
● Toute la puissance (et les inconvénients) d'une base de données relationnelle dans le navigateur
● Taille de stockage bien supérieure à 5MB (potentiellement jusqu'à 1GB)
● La plupart des implémentations reposent sur SQLLite
● Implémentation supportée par les navigateurs mobiles
WebSQL - Normalisation
Web SQL Database - Ouverture de BDD
var db = window.openDatabase(
"MyDB",
"","My super database",1024);
Web SQL Database Vérification de la version
Gérer les versions de la base et la création des tablesif (db.version != "1") {
db.changeVersion(db.version, "1", function(tx) { // User's first visit. Initialize database. var tables = [ { name: "users", columns: ["id INTEGER PRIMARY KEY", "name TEXT"]}, { name: "groups", columns: ["id INTEGER PRIMARY KEY", "name TEXT"]}, { name: "users_groups", columns: ["userId INTEGER", "groupId INTEGER", date TEXT"]} ];
for (var index = 0; index < tables.length; index++) { var table = tables[index]; tx.executeSql("CREATE TABLE " + table.name + "(" + table.columns.join(", ") + ");");
}
}, null, function() {loadData(db);});
}else { // User has been here before, no initialization required. loadData(db);
}
WebDatabase : insertion de données
db.transaction(function(tx) { for (var index = 0; index < myTable.length; index++) { var myValue = myTable[index]; tx.executeSql("INSERT INTO users (name) VALUES (:name);", [myValue], function(tx, results) {
// Do something here after the insert }); }});
WebDatabase : lecture d'enregistrements
db.readTransaction(function(tx) {
tx.executeSql("SELECT * FROM users", function(tx, results) {
var rows = results.rows; for (var index = 0; index < rows.length; index++) {
var item = rows.item(index); var element = document.createElement("div"); element.textContent = item.name;
document.getElementById("usersList").appendChild(element); }
});}
);
WebDatabase : support des navigateurs
● Fonctionnalité non supportée par Firefox
● A venir dans IE
IndexedDB
● Une alternative à WebDB avec les mêmes objectifs : fournir une solution de stockage local avancé pour les applications HTML5
● Repose sur une implémentation "NoSQL" basée sur un concept de "DataStore"
● L'ensemble des accès est asynchrone
IndexedDB - Code
Ouverture de la base et vérification de la versionvar request = window.indexedDB.open("MyDB“, "My great database");request.onsuccess = function(event) {
var db = event.result; if (db.version != "1") {
// User's first visit, initialize database. var createdObjectStoreCount = 0; var objectStores = [
{ name: "users", keyPath: "id", autoIncrement: true }, { name: "groups", keyPath: "id", autoIncrement: true }, { name: "users_groups", keyPath: "", autoIncrement: true } ];
function objectStoreCreated(event) { if (++createdObjectStoreCount == objectStores.length) {
db.setVersion("1").onsuccess = function(event) { loadData(db);}; }
}
for (var index = 0; index < objectStores.length; index++) { var params = objectStores[index]; request = db.createObjectStore(params.name, params.keyPath, params.autoIncrement); request.onsuccess = objectStoreCreated;
} } else {
loadData(db); }
};
IndexedDB : insertion de données
var request = window.indexedDB.open("MyDB", "My great database");request.onsuccess = function(event) {
var objectStore = event.result.objectStore("users"); for (var index = 0; index < users.length; index++) {
var user = users[index]; objectStore.add(user).onsuccess = function(event) {
document.getElementById("display").textContent = "Saved record for " + user.name + " with id " + event.result;
}; }
};
indexedDB : lecture d'enregistrements
var request = window.indexedDB.open("MyDB", "My great database");request.onsuccess = function(event) { // Enumerate the entire object store. request = event.result.objectStore("users").openCursor(); request.onsuccess = function(event) { var cursor = event.result; // If cursor is null then we've completed the enumeration. if (!cursor) { return; } var element = document.createElement("div"); element.textContent = cursor.value.name; document.getElementById("usersList").appendChild(element); cursor.continue(); };};
indexedDB : Browser support
Synthèse : support des browsers
source : http://www.html5rocks.com/en/features/storage
Wrappers javascript
● Lawnchair : ● une interface unifiée qui supporte les différentes implémentations
● IndexedDB Polyfill● Wrapper IndexedDB autour de WebSQL
Stockage des pages et ressources associées dans le navigateur
● Utilisation d'un fichier "Manifest" permettant de décrire le comportement des ressources
● Un seul fichier Manifest à la racine de la WebApp, toutes les pages de la WebApp pointant sur ce fichier
Structure d'un fichier Manifest
● Un MIME Type spécfique: text/cache-manifest● Utilisation d’une extension “ .appcache”● Header d'un fichier manifest : CACHE MANIFEST● 3 sections :
● CACHE : liste les ressources devant être obligatoirement mises en cache
● NETWORK : liste les ressources nécessitant obligatoirement d'être connecté. La wilcard * permet d'ajouter au cache les ressources référencées sur d'autres domaines
● FALLBACK : liste les ressources à afficher lorsque la page consultée en offline n'est pas dans le cache
Exemple de fichier ManifestCACHE MANIFEST
# rev 42
NETWORK:/tracking.cgi
CACHE:/clock.css/clock.js/clock-face.jpg
FALLBACK:
/ /pageNotFound.html
Manipulation du cache par Javascript
● Différents événements renvoyés lorsque le navigateur lit lanifeste
● Accès programmatique au cache : window.applicationCache
var appCache = window.applicationCache;
appCache.update();
if (appCache.status == window.applicationCache.UPDATEREADY) { appCache.swapCache();
}
Trucs et astuces sur AppCache● Utilisez des outils de génération automatique du Manifeste (ex:
HTML5 BoilerPlate)
● En mode développement, configurez votre serveur Web pour un TTL de 0 pour servir le fichier Manifeste.
● Possibilité de voir le contenu du cache● Sous Chrome : chrome:appcache-internals
Détection des modes offline / online● fonction navigator.online()
● permet de détecter si le navigateur est connecté
● Evénements :● document.body.addEventListener("online", function () {...}● document.body.addEventListener("offline", function () {...}
● Attention, navigator.online() renvoie true dès qu’on est connecté à un réseau mais sans nécessairement de connexion internet
● Possibilité d’implémenter un polling par xmlHTTPRequest