SlideShare ist ein Scribd-Unternehmen logo
Offline. Na und?
Strategien für offlinefähige
Applikationen in HTML5
Stephan Hochdörfer, bitExpert AG
Offline. Na und? - Strategien für offlinefähige Applikationen
Über mich
 Stephan Hochdörfer
 Head of IT der bitExpert AG, Mannheim
 S.Hochdoerfer@bitExpert.de
 @shochdoerfer
Offline. Na und? - Strategien für offlinefähige Applikationen
Daten auf dem Client speichern?
Offline. Na und? - Strategien für offlinefähige Applikationen
Wie wurde dies in der Vergangenheit gelöst?
Offline. Na und? - Strategien für offlinefähige Applikationen
Cookies. Lecker aber mehr auch nicht.
Offline. Na und? - Strategien für offlinefähige Applikationen
IE DHTML Behaviours
Offline. Na und? - Strategien für offlinefähige Applikationen
Flash Cookies schmecken auch lecker.
Offline. Na und? - Strategien für offlinefähige Applikationen
Google Gears mit neuem Ansatz.
Gibt es nichts wirklich sinnvolles?
Offline. Na und? - Strategien für offlinefähige Applikationen
Offline. Na und? - Strategien für offlinefähige Applikationen
als Lösung...
Offline. Na und? - Strategien für offlinefähige Applikationen
[...] we take the next step,
announcing 2014 as the target for
Recommendation.
Jeff Jaffe, Chief Executive Officer, World Wide Web Consortium
Offline. Na und? - Strategien für offlinefähige Applikationen
Offline. Na und? - Strategien für offlinefähige Applikationen
Was bedeutet „offline“?
Offline. Na und? - Strategien für offlinefähige Applikationen
Was bedeutet „offline“?
Offline. Na und? - Strategien für offlinefähige Applikationen
Applikation vs. Content
Was bedeutet „offline“?
Offline. Na und? - Strategien für offlinefähige Applikationen
Application Cache vs. Offline Storage
App Cache für statische Ressourcen
Offline. Na und? - Strategien für offlinefähige Applikationen
<!DOCTYPE html>
<html lang="en">
HTML Page:
<!DOCTYPE html>
<html lang="en" manifest="cache.manifest">
App Cache für statische Ressourcen
Offline. Na und? - Strategien für offlinefähige Applikationen
HTML Page:
cache.manifest (Content-Type: text/cache-manifest):
CACHE MANIFEST
js/app.js
css/app.css
favicon.ico
http://someotherdomain.com/image.png
App Cache für statische Ressourcen
Offline. Na und? - Strategien für offlinefähige Applikationen
CACHE MANIFEST
# 2012-09-16
NETWORK:
data.php
CACHE:
/main/home
/main/app.js
/settings/home
/settings/app.js
http://myhost/logo.png
http://myhost/check.png
http://myhost/cross.png
App Cache für statische Ressourcen
Offline. Na und? - Strategien für offlinefähige Applikationen
CACHE MANIFEST
# 2012-09-16
FALLBACK:
/ /offline.html
NETWORK:
*
App Cache Scripting
Offline. Na und? - Strategien für offlinefähige Applikationen
// events fired by window.applicationCache
window.applicationCache.onchecking = function(e)
{log("Checking for updates");}
window.applicationCache.onnoupdate = function(e)
{log("No updates");}
window.applicationCache.onupdateready = function(e)
{log("Update ready");}
window.applicationCache.onobsolete = function(e)
{log("Obsolete");}
window.applicationCache.ondownloading = function(e)
{log("Downloading");}
window.applicationCache.oncached = function(e)
{log("Cached");}
window.applicationCache.onerror = function(e)
{log("Error");}
// Log each file
window.applicationCache.onprogress = function(e) {
log("Progress: downloaded file " + counter);
counter++;
};
App Cache Scripting
Offline. Na und? - Strategien für offlinefähige Applikationen
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready',
function(e) {
if(window.applicationCache.status ==
window.applicationCache.UPDATEREADY) {
// Browser downloaded a new app cache.
// Swap it in and reload the page
window.applicationCache.swapCache();
if (confirm('New version is available. Load it?)) {
window.location.reload();
}
} else {
// Manifest didn't change...
}
}, false);
}, false);
App Cache – Einige Fallstricke!
Offline. Na und? - Strategien für offlinefähige Applikationen
App Cache – Einige Fallstricke!
Offline. Na und? - Strategien für offlinefähige Applikationen
1. Dateien werden immer(!) vom
lokalen Cache ausgeliefert.
App Cache – Einige Fallstricke!
Offline. Na und? - Strategien für offlinefähige Applikationen
2. Der lokale Cache wird nur dann
aktualisiert wenn sich die manifest
Datei geändert hat.
App Cache – Einige Fallstricke!
Offline. Na und? - Strategien für offlinefähige Applikationen
3. Nicht ladbare Dateien aus der
CACHE Sektion führen dazu dass der
Cache invalide ist.
App Cache – Einige Fallstricke!
Offline. Na und? - Strategien für offlinefähige Applikationen
4. Kann die manifest Datei nicht
geladen werden, erfolgt kein Caching!
App Cache – Einige Fallstricke!
Offline. Na und? - Strategien für offlinefähige Applikationen
5. Nicht gecachte Ressourcen werden
auf einer gecachten Seite nicht
angezeigt.
App Cache – Einige Fallstricke!
Offline. Na und? - Strategien für offlinefähige Applikationen
6. Nach Aktualisierung des Caches
muss die Seite neu geladen werden!
App Cache – Einige Fallstricke!
Offline. Na und? - Strategien für offlinefähige Applikationen
7. Mit expires Header arbeiten um das
Cachen des manifests zu verhinden!
App Cache – Cache Manifest Validator
Offline. Na und? - Strategien für offlinefähige Applikationen
http://manifest-validator.com
App Cache – Was darf gecacht werden?
Offline. Na und? - Strategien für offlinefähige Applikationen
App Cache – Was darf gecacht werden?
Offline. Na und? - Strategien für offlinefähige Applikationen
Ja:

Schriften

Startbild

Applikationsicon

Einstiegsseite

Fallbackseite
Nein:

CSS

HTML

Javascript
App Cache – Was darf gecacht werden?
Offline. Na und? - Strategien für offlinefähige Applikationen
Den App Cache nur für
„statischen Content“ verwenden!
Ausflug: Data URI Schema
Offline. Na und? - Strategien für offlinefähige Applikationen
<!DOCTYPE HTML>
<html>
 <head>
  <title>The Data URI scheme</title>
  <style type="text/css">
  ul.checklist li {
    margin­left: 20px;
    background: white 
url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAA
AFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAA
O9TXL0Y4OHwAAAABJRU5ErkJggg==') no­repeat scroll left 
top;
}
  </style>
 </head>
 <body>
  <img 
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAA
AFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAA
O9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">
 </body>
</html>
Ausflug: Data URI Schema
Offline. Na und? - Strategien für offlinefähige Applikationen
Dynamische Daten lokal speichern...
Offline. Na und? - Strategien für offlinefähige Applikationen
Offline. Na und? - Strategien für offlinefähige Applikationen
Beispiel: Todoliste
Dynamische Daten lokal speichern...
Offline. Na und? - Strategien für offlinefähige Applikationen
Sourcen:
github.com/bitExpert/html5-offline
Dynamische Daten lokal speichern...
Offline. Na und? - Strategien für offlinefähige Applikationen
Web Storage, Web SQL Database,
IndexedDB, File API
Web Storage
Offline. Na und? - Strategien für offlinefähige Applikationen
Web Storage
Offline. Na und? - Strategien für offlinefähige Applikationen
Komfortable Art Daten offline zu
speichern: Key/Value Speicher
Web Storage: 2 Arten
Offline. Na und? - Strategien für offlinefähige Applikationen
localStorage vs. sessionStorage
Web Storage: Datensatz hinzufügen
Offline. Na und? - Strategien für offlinefähige Applikationen
function add(item) {
try {
// for a new item set id
if((typeof item.id === "undefined")
|| (null == item.id) || ("" == item.id)) {
item.id = get_lastIndex() + 1;
}
// store object as string
localStorage.setItem(item.id,
JSON.stringify(item)
);
// update the index
set_lastIndex(item.id);
}
catch(ex) {
console.log(ex);
}
}
Web Storage: Datensatz ändern
Offline. Na und? - Strategien für offlinefähige Applikationen
function modify(item) {
try {
// store object as string
localStorage.setItem(item.id,
JSON.stringify(item)
);
}
catch(ex) {
console.log(ex);
}
}
Web Storage: Datensatz löschen
Offline. Na und? - Strategien für offlinefähige Applikationen
function remove (id) {
try {
localStorage.removeItem(id);
}
catch(ex) {
console.log(ex);
}
}
Web Storage: Datensätze auslesen
Offline. Na und? - Strategien für offlinefähige Applikationen
function read() {
try {
var lastIdx = get_lastIndex();
for(var i = 1; i <= lastIdx; i++) {
if(null !== localStorage.getItem(i)) {
// parse and render item
var item = JSON.parse(
localStorage.getItem(i)
);
}
}
}
catch(ex) {
console.log(ex);
}
}
Web Storage: Wie sessionStorage nutzen?
Offline. Na und? - Strategien für offlinefähige ApplikationenOffline. Na und? - Strategien für offlinefähige Applikationen
Web Storage: Wie sessionStorage nutzen?
Offline. Na und? - Strategien für offlinefähige Applikationen
Einfach: Ersetze „localStorage“
durch „sessionStorage“
Web Storage: Datensatz hinzufügen
Offline. Na und? - Strategien für offlinefähige Applikationen
function add(item) {
try {
// for a new item set id
if((typeof item.id === "undefined")
|| (null == item.id) || ("" == item.id)) {
item.id = get_lastIndex() + 1;
}
// store object as string
sessionStorage.setItem(item.id,
JSON.stringify(item)
);
// update the index
set_lastIndex(item.id);
}
catch(ex) {
console.log(ex);
}
}
Web Storage: sessionStorage Fallstrick
Offline. Na und? - Strategien für offlinefähige Applikationen
Jedes Tab / Fenster bringt
eigenen sessionStorage mit sich!
Web Storage: Alternative Zugriffsmöglichkeiten
Offline. Na und? - Strategien für offlinefähige Applikationen
var value = "my value";
// method call
localStorage.setItem("key", value);
// Array accessor
localStorage[key] = value;
// Property accessor
localStorage.key = value;
Offline. Na und? - Strategien für offlinefähige Applikationen
Welche Daten sind gespeichert?
Web Storage: Vorteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Die meisten der aktuellen Browser
„können“ Web Storage.
Web Storage: Vorteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Funktioniert sogar im IE8 :)
Web Storage: Vorteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Kein HTTP Overhead
wie bsp. bei Cookies.
Web Storage: Nachteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Daten werden unstrukturiert
gespeichert.
Web Storage: Nachteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Nicht transaktionsfähig!
Web Storage: Nachteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Nicht asynchron!
Web Storage: Nachteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Daten können nicht automatisch
verfallen. Manueller Aufwand nötig.
Web Storage: Nachteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Unzureichende Informationen wie
voll der lokale Cache wirklich ist.
Web Storage: Nachteile
Offline. Na und? - Strategien für offlinefähige Applikationen
http:// und https:// definieren
unterschiedliche Storages.
Web SQL Database
Offline. Na und? - Strategien für offlinefähige Applikationen
Web SQL Database
Offline. Na und? - Strategien für offlinefähige Applikationen
Eine lokale SQL Datenbank
auf SQLite Basis.
Web SQL Database: Callbacks
Offline. Na und? - Strategien für offlinefähige Applikationen
var onError = function(tx, ex) {
alert("Error: " + ex.message);
};
var onSuccess = function(tx, results) {
var len = results.rows.length;
for(var i = 0; i < len; i++) {
// render found todo item
render(results.rows.item(i));
}
};
Web SQL Database: Datenbank erzeugen
Offline. Na und? - Strategien für offlinefähige Applikationen
// initalize the database connection
var db = openDatabase('todo', '1.0', 'Todo Database',
5 * 1024 * 1024 );
db.transaction(function (tx) {
tx.executeSql(
'CREATE TABLE IF NOT EXISTS todo '+
'(id INTEGER PRIMARY KEY ASC, todo TEXT)',
[],
onSuccess,
onError
);
});
Web SQL Database: Datenbankmigration
Offline. Na und? - Strategien für offlinefähige Applikationen
function m1(t){ t.executeSql("create table tbl1...") }
function m2(t){ t.executeSql("alter table tbl1...") }
function m3(t){ t.executeSql("alter table tbl1...") }
if(db.version == "") {
db.changeVersion("", "1", m1, null, function() {
db.changeVersion("1", "2", m2, null, function() {
db.changeVersion("2", "3", m3);
});
});
}
if(db.version == "1") {
db.changeVersion("1", "2", m2, null, function() {
db.changeVersion("2", "3", m3);
});
}
if(db.version == "2") {
db.changeVersion("2", "3", m3);
}
Web SQL Database: Datensatz hinzufügen
Offline. Na und? - Strategien für offlinefähige Applikationen
function add(item) {
db.transaction(function(tx) {
tx.executeSql(
'INSERT INTO todo (todo) VALUES (?)',
[
item.todo
],
onSuccess,
onError
);
});
}
Web SQL Database: Datensatz verändern
Offline. Na und? - Strategien für offlinefähige Applikationen
function modify(item) {
db.transaction(function(tx) {
tx.executeSql(
'UPDATE todo SET todo = ? WHERE id = ?',
[
item.todo
item.id
],
onSuccess,
onError
);
});
}
Web SQL Database: Datensatz löschen
Offline. Na und? - Strategien für offlinefähige Applikationen
function remove(id) {
db.transaction(function (tx) {
tx.executeSql(
'DELETE FROM todo WHERE id = ?',
[
id
],
onSuccess,
onError
);
});
}
Web SQL Database: Datensätze auslesen
Offline. Na und? - Strategien für offlinefähige Applikationen
function read() {
db.transaction(function (tx) {
tx.executeSql(
'SELECT * FROM todo',
[],
onSuccess,
onError
);
});
}
Web SQL Database: Vorteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Eine SQL Datenbank im Browser!
Web SQL Database: Nachteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Eine SQL Datenbank im Browser!
Web SQL Database: Nachteile
Offline. Na und? - Strategien für offlinefähige Applikationen
SQLite kann seeeehr langsam sein!
Web SQL Database: Nachteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Nicht länger Teil der
HTML5 Spezifikation!
IndexedDB
Offline. Na und? - Strategien für offlinefähige Applikationen
IndexedDB
Offline. Na und? - Strategien für offlinefähige Applikationen
Kompromiss aus Web Storage
und Web SQL Database.
IndexedDB
Offline. Na und? - Strategien für offlinefähige Applikationen
Die NoSQL Datenbank für
den Browser.
Web SQL Database vs. IndexedDB
Offline. Na und? - Strategien für offlinefähige Applikationen
Kategorie Web SQL IndexedDB
Speicherart Tabellen mit Spalten und
Zeilen
Objectstore mit Javascript Objekten und
Keys
Abfrage
mechanismus
SQL Cursor APIs, Key Range APIs und
Applicationslogik
Transaktionali
tät
Lock für Databanken,
Tabellen oder Zeilen bei
READ_WRITE Transaktionen
Locks für Datenbanken
(VERSION_CHANGE Transaktion) und
Objectstores (READ_ONLY, READ_WRITE
Transaktion).
Transaktions-
Commits
Transaktionen werden explizt
erzeugt. Standard: Rollback,
außer es wird explizit ein
commit ausgeführt.
Transaktionen werden explizt erzeugt.
Standard: Committen sofern kein Fehler
aufgetreten ist.
IndexedDB: Vorarbeiten
Offline. Na und? - Strategien für offlinefähige Applikationen
// different browsers, different naming conventions
var indexedDB = window.indexedDB ||
window.webkitIndexedDB || window.mozIndexedDB ||
window.msIndexedDB;
var IDBTransaction = window.IDBTransaction ||
window.webkitIDBTransaction;
var IDBKeyRange = window.IDBKeyRange ||
window.webkitIDBKeyRange;
IndexedDB: Objektspeicher erzeugen
Offline. Na und? - Strategien für offlinefähige Applikationen
var db = null;
var request = indexedDB.open("todo");
request.onfailure = onError;
request.onsuccess = function(e) {
db = request.result;
var v = "1.0";
if(v != db.version) {
var verRequest = db.setVersion(v);
verRequest.onfailure = onError;
verRequest.onsuccess = function(e) {
var store = db.createObjectStore(
"todo",
{
keyPath: "id",
autoIncrement: true
}
);
e.target.transaction.oncomplete =
function() {};
};
}
};
IndexedDB: Datensatz hinzufügen
Offline. Na und? - Strategien für offlinefähige Applikationen
function add(item) {
try {
var trans = db.transaction(["todo"],
IDBTransaction.READ_WRITE);
var store = trans.objectStore("todo");
var request = store.put({
"todo": item.todo,
});
}
catch(ex) {
onError(ex);
}
}
IndexedDB: Datensatz verändern
Offline. Na und? - Strategien für offlinefähige Applikationen
function modify(item) {
try {
var trans = db.transaction(["todo"],
IDBTransaction.READ_WRITE);
var store = trans.objectStore("todo");
var request = store.put(item);
}
catch(ex) {
onError(ex);
}
}
IndexedDB: Datensatz löschen
Offline. Na und? - Strategien für offlinefähige Applikationen
function remove(id) {
try {
var trans = db.transaction(["todo"],
IDBTransaction.READ_WRITE);
var store = trans.objectStore("todo");
var request = store.delete(id);
}
catch(ex) {
onError(ex);
}
}
IndexedDB: Datensätze auslesen
Offline. Na und? - Strategien für offlinefähige Applikationen
function read () {
try {
var trans = db.transaction(["todo"],
IDBTransaction.READ);
var store = trans.objectStore("todo");
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
if(!!result == false) {
return;
}
// @TODO: render result.value
result.continue();
};
}
catch(ex) {
onError(ex);
}
}
IndexedDB: Datensatz mittels Index auslesen
Offline. Na und? - Strategien für offlinefähige Applikationen
try {
var index = db.openIndex('todo');
var item = index.get(1337);
}
catch(ex) {
onError(ex);
}
IndexedDB: Index erzeugen
Offline. Na und? - Strategien für offlinefähige Applikationen
try {
// create non-unique index
db.createIndex("Created", "createdDate",
{"unique": false});
// create unique index
db.createIndex("OtherKey", "otherField",
{"unique": true});
// create multi-column index (not working in IE10!)
db.createIndex("MultiIndex", ["field1", "field2"]);
}
catch(ex) {
onError(ex);
}
IndexedDB: Zu kompliziert?
Offline. Na und? - Strategien für offlinefähige Applikationen
IndexedDB: Zu kompliziert?
Offline. Na und? - Strategien für offlinefähige Applikationen
db.js als Wrapper nutzen
IndexedDB: db.js als Wrapper
Offline. Na und? - Strategien für offlinefähige Applikationen
var server;
db.open( {
server: 'todo',
version: 1,
schema: {
todo: {
key: { keyPath: 'id' , autoIncrement: true},
indexes: {
Created: { }
}
}
}
}).done(function(s) {
server = s;
});
IndexedDB: db.js als Wrapper
Offline. Na und? - Strategien für offlinefähige Applikationen
server.todo.add( {
todo: 'This is a sample todo item'
}).done(function(item) {
// item stored
});
IndexedDB: db.js als Wrapper
Offline. Na und? - Strategien für offlinefähige Applikationen
server.todo.query()
.execute()
.done(function(results) {
// do something with the results
});
IndexedDB: Vorteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Neuer Standard der künftig durch
viele Browser unterstützt wird.
IndexedDB: Nachteile
Offline. Na und? - Strategien für offlinefähige Applikationen
Nicht alle mobilen Browser
untersützen IndexedDB.
IndexedDB Polyfill
Offline. Na und? - Strategien für offlinefähige Applikationen
IndexedDB Emulation via WebSQL:
http://nparashuram.com/IndexedDBShim
File API
Offline. Na und? - Strategien für offlinefähige Applikationen
File API
Offline. Na und? - Strategien für offlinefähige Applikationen
FileReader API und FileWriter API
File API: Vorarbeiten
Offline. Na und? - Strategien für offlinefähige Applikationen
var onError = function(e) {
var msg = '';
switch(e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR'; break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR'; break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR'; break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR'; break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR'; break;
default:
msg = 'Unknown Error'; break;
};
alert("Error: " + msg);
};
File API: Vorarbeiten II
Offline. Na und? - Strategien für offlinefähige Applikationen
// File system has been prefixed as of Google Chrome 12
window.requestFileSystem = window.requestFileSystem ||
window.webkitRequestFileSystem;
window.BlobBuilder = window.BlobBuilder ||
window.WebKitBlobBuilder;
var size = 5 * 1024*1024; // 5MB
File API: Quota anfordern
Offline. Na und? - Strategien für offlinefähige Applikationen
// request quota for persistent store
window.webkitStorageInfo.requestQuota(
PERSISTENT,
size,
function(grantedBytes) {
window.requestFileSystem(
PERSISTENT,
grantedBytes,
function(fs) {
// @TODO: access filesystem
}
}
}
}
Offline. Na und? - Strategien für offlinefähige Applikationen
File API: Daten hinzufügen
Offline. Na und? - Strategien für offlinefähige Applikationen
function add(item) {
window.webkitStorageInfo.requestQuota(
PERSISTENT,
size,
function(grantedBytes) {
window.requestFileSystem(
PERSISTENT,
grantedBytes,
function(fs){
writeToFile(fs, item);
},
onError
);
},
function(e) {
onError(e);
}
);
}
File API: Daten hinzufügen II
Offline. Na und? - Strategien für offlinefähige Applikationen
function writeToFile(fs, item) {
fs.root.getFile(
'todo.txt',
{
create: true
},
function(fileEntry) {
fileEntry.createWriter(
function(fileWriter) {
var bb = new window.BlobBuilder();
bb.append(JSON.stringify(item)+
"n");
fileWriter.seek(fileWriter.length);
fileWriter.write(
bb.getBlob('text/plain'));
}, onError
);
}, onError
);
}
File API: Daten hinzufügen II
Offline. Na und? - Strategien für offlinefähige Applikationen
function writeToFile(fs, item) {
fs.root.getFile(
'todo.txt',
{
create: true
},
function(fileEntry) {
fileEntry.createWriter(
function(fileWriter) {
var bb = new window.BlobBuilder();
bb.append(JSON.stringify(item)+
"n");
fileWriter.seek(fileWriter.length);
fileWriter.write(
bb.getBlob('text/plain'));
}, onError
);
}, onError
);
}
Deprecated!
File API: Daten hinzufügen II
Offline. Na und? - Strategien für offlinefähige Applikationen
function writeToFile(fs, item) {
fs.root.getFile(
'todo.txt',
{
create: true
},
function(fileEntry) {
fileEntry.createWriter(
function(fileWriter) {
var blob = new Blob([
JSON.stringify(item)+"n"
]);
fileWriter.seek(fileWriter.length);
fileWriter.write(blob);
}, onError
);
}, onError
);
}
File API: Daten auslesen
Offline. Na und? - Strategien für offlinefähige Applikationen
function read() {
window.webkitStorageInfo.requestQuota(
PERSISTENT,
size,
function(grantedBytes) {
window.requestFileSystem(
PERSISTENT,
grantedBytes,
function(fs){
readFromFile(fs);
},
onError
);
},
function(e) {
onError(e);
}
);
}
File API: Daten auslesen II
Offline. Na und? - Strategien für offlinefähige Applikationen
function readFromFile(fs) {
fs.root.getFile(
'todo.txt',
{
create: true
},
function(fileEntry) {
fileEntry.file(function(file){
var reader = new FileReader();
reader.onloadend = function(e) {
if (evt.target.readyState ==
FileReader.DONE) {
// process this.result
}
};
reader.readAsText(file);
});
}, onError
);
}
Bin ich online?
Offline. Na und? - Strategien für offlinefähige Applikationen
Bin ich online?
Offline. Na und? - Strategien für offlinefähige Applikationen
document.body.addEventListener("online", function () {
// browser is online!
}
document.body.addEventListener("offline", function () {
// browser is not online!
}
Bin ich online? Andere Vorgehensweise...
Offline. Na und? - Strategien für offlinefähige Applikationen
$.ajax({
dataType: 'json',
url: 'http://myappurl.com/ping',
success: function(data){
// ping worked
},
error: function() {
// ping failed -> Server not reachable
}
});
Datensynchronisation
Offline. Na und? - Strategien für offlinefähige Applikationen
Datensynchronisation
Offline. Na und? - Strategien für offlinefähige Applikationen
PouchDB, the JavaScript
Database that syncs!
Datensynchronisation
Offline. Na und? - Strategien für offlinefähige Applikationen
var db = new PouchDB('todo');
db.put({
_id: 1,
todo: 'Get some work done...',
});
db.replicate.to('http://example.com/mydb');
NoBackend Bewegung
Offline. Na und? - Strategien für offlinefähige Applikationen
NoBackend Bewegung
Offline. Na und? - Strategien für offlinefähige Applikationen
Entkopplung von Frontend
und Backend!
NoBackend Bewegung: Hood.ie
Offline. Na und? - Strategien für offlinefähige Applikationen
„Hoodie is an architecture for
frontend-only web apps“
Browserunterstützung?
Offline. Na und? - Strategien für offlinefähige Applikationen
Browserunterstützung?
Offline. Na und? - Strategien für offlinefähige Applikationen
App Cache Web Storage WebSQL IndexedDB File API Data URI
IE 10.0 8.0 10.0 10.0 - 8.0*
Firefox 11.0 11.0 11.0 11.0 19.0 16.0
Chrome 18.0 18.0 18.0 18.0 18.0 18.0
Safari 5.1 5.1 5.1 - - 5.1
Opera 12.1 12.1 12.1 - - 12.1
iOS Safari 3.2 3.2 3.2 - - 3.2
Android 2.1 2.1 2.1 - - 2.1
Quelle: http://caniuse.com
Speicherplatzbeschränkung?
Offline. Na und? - Strategien für offlinefähige Applikationen
Speicherplatzbeschränkung?
Offline. Na und? - Strategien für offlinefähige Applikationen
Alle vorgestellten Technologien sind
durch Quotas beschränkt.
Speicherplatzbeschränkung?
Offline. Na und? - Strategien für offlinefähige Applikationen
App Cache Web Storage WebSQL IndexedDB File API
iOS 5.1 10 MB 5 MB 5 MB 5 MB
Android 4 unlimited 5 MB ? ?
Safari 5.2 unlimited 5 MB 5 MB 5 MB
Chrome 18 5 MB 5 MB unlimited unlimited unlimited
IE 10 50 MB 10 MB 500 MB 500 MB
Opera 11 50 MB 5 MB 5 MB 5 MB
Firefox 11 unlimited 10 MB 50 MB 50 MB
Minimumwerte, je nach Konfiguration ist mehr möglich.
Vielen Dank!

Weitere ähnliche Inhalte

Ähnlich wie Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbstcampus13

HTML5 Offline - Fallstricke für mobile Webseiten und WebApps
HTML5 Offline - Fallstricke für mobile Webseiten und WebAppsHTML5 Offline - Fallstricke für mobile Webseiten und WebApps
HTML5 Offline - Fallstricke für mobile Webseiten und WebApps
Ulrich Schmidt
 
Gewinnung von OPEN SOURCE Techniken für junge Unternehmen
Gewinnung von OPEN SOURCE Techniken für junge UnternehmenGewinnung von OPEN SOURCE Techniken für junge Unternehmen
Gewinnung von OPEN SOURCE Techniken für junge Unternehmen
Bjoern Reinhold
 
Mobile Webentwicklung mit HTML5
Mobile Webentwicklung mit HTML5Mobile Webentwicklung mit HTML5
Mobile Webentwicklung mit HTML5
kkramhoeft
 
German: Softwareprodukte aus einem Source Code mit Javascript
German: Softwareprodukte aus einem Source Code mit JavascriptGerman: Softwareprodukte aus einem Source Code mit Javascript
German: Softwareprodukte aus einem Source Code mit Javascript
Ralf Schwoebel
 
Offlinefähige Browseranwendungen: Progressive Web-Apps mit Angular 2
Offlinefähige Browseranwendungen: Progressive Web-Apps mit Angular 2Offlinefähige Browseranwendungen: Progressive Web-Apps mit Angular 2
Offlinefähige Browseranwendungen: Progressive Web-Apps mit Angular 2
Manfred Steyer
 
GAUC 2017 Workshop App Tracking: Markus Vollmert (lunapark)
GAUC 2017 Workshop App Tracking: Markus Vollmert (lunapark)GAUC 2017 Workshop App Tracking: Markus Vollmert (lunapark)
GAUC 2017 Workshop App Tracking: Markus Vollmert (lunapark)
e-dialog GmbH
 
Schnelle Winkel: 10x schnellere Webapps mit AngularJS und JEE
Schnelle Winkel: 10x schnellere Webapps mit AngularJS und JEESchnelle Winkel: 10x schnellere Webapps mit AngularJS und JEE
Schnelle Winkel: 10x schnellere Webapps mit AngularJS und JEE
Benjamin Schmid
 
Sencha Touch & PhoneGap
Sencha Touch & PhoneGapSencha Touch & PhoneGap
Sencha Touch & PhoneGap
Stefan Kolb
 
Google Analytics & Seo @seosixt wiesn 2014
Google Analytics & Seo @seosixt wiesn 2014Google Analytics & Seo @seosixt wiesn 2014
Google Analytics & Seo @seosixt wiesn 2014
121WATT GmbH
 
Einführung in die webOS Programmierung
Einführung in die webOS ProgrammierungEinführung in die webOS Programmierung
Einführung in die webOS Programmierung
Markus Leutwyler
 
Smartes SEO Monitoring & Alerting mit Apps Scripts [DE] - John Muñoz
Smartes SEO Monitoring & Alerting mit Apps Scripts [DE] - John MuñozSmartes SEO Monitoring & Alerting mit Apps Scripts [DE] - John Muñoz
Smartes SEO Monitoring & Alerting mit Apps Scripts [DE] - John Muñoz
John Muñoz
 
Logstash: Windows und Linux Logmanagement (Webinar vom 07.11.2014)
Logstash: Windows und Linux Logmanagement (Webinar vom 07.11.2014)Logstash: Windows und Linux Logmanagement (Webinar vom 07.11.2014)
Logstash: Windows und Linux Logmanagement (Webinar vom 07.11.2014)
NETWAYS
 
APEX 5.0, und sonst?
APEX 5.0, und sonst?APEX 5.0, und sonst?
APEX 5.0, und sonst?
Niels de Bruijn
 
Mobile Web Development from Scratch
Mobile Web Development from ScratchMobile Web Development from Scratch
Mobile Web Development from Scratch
NokiaAppForum
 
Sencha Touch und PhoneGap
Sencha Touch und PhoneGapSencha Touch und PhoneGap
Sencha Touch und PhoneGap
Indiginox
 
Testing einer Angular App
Testing einer Angular AppTesting einer Angular App
Testing einer Angular App
Florian Bader
 
Google Analytics Konferenz 2019_App Tracking_Runa Reno (Booking.com) & Markus...
Google Analytics Konferenz 2019_App Tracking_Runa Reno (Booking.com) & Markus...Google Analytics Konferenz 2019_App Tracking_Runa Reno (Booking.com) & Markus...
Google Analytics Konferenz 2019_App Tracking_Runa Reno (Booking.com) & Markus...
e-dialog GmbH
 
HTML5-Legacy-Anwendungen
HTML5-Legacy-AnwendungenHTML5-Legacy-Anwendungen
HTML5-Legacy-Anwendungen
Jonathan Weiß
 
Webinar - ABAP Development Tools
Webinar - ABAP Development ToolsWebinar - ABAP Development Tools
Webinar - ABAP Development Tools
Cadaxo GmbH
 

Ähnlich wie Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbstcampus13 (20)

HTML5 Offline - Fallstricke für mobile Webseiten und WebApps
HTML5 Offline - Fallstricke für mobile Webseiten und WebAppsHTML5 Offline - Fallstricke für mobile Webseiten und WebApps
HTML5 Offline - Fallstricke für mobile Webseiten und WebApps
 
Hdc2012 cordova-präsi
Hdc2012 cordova-präsiHdc2012 cordova-präsi
Hdc2012 cordova-präsi
 
Gewinnung von OPEN SOURCE Techniken für junge Unternehmen
Gewinnung von OPEN SOURCE Techniken für junge UnternehmenGewinnung von OPEN SOURCE Techniken für junge Unternehmen
Gewinnung von OPEN SOURCE Techniken für junge Unternehmen
 
Mobile Webentwicklung mit HTML5
Mobile Webentwicklung mit HTML5Mobile Webentwicklung mit HTML5
Mobile Webentwicklung mit HTML5
 
German: Softwareprodukte aus einem Source Code mit Javascript
German: Softwareprodukte aus einem Source Code mit JavascriptGerman: Softwareprodukte aus einem Source Code mit Javascript
German: Softwareprodukte aus einem Source Code mit Javascript
 
Offlinefähige Browseranwendungen: Progressive Web-Apps mit Angular 2
Offlinefähige Browseranwendungen: Progressive Web-Apps mit Angular 2Offlinefähige Browseranwendungen: Progressive Web-Apps mit Angular 2
Offlinefähige Browseranwendungen: Progressive Web-Apps mit Angular 2
 
GAUC 2017 Workshop App Tracking: Markus Vollmert (lunapark)
GAUC 2017 Workshop App Tracking: Markus Vollmert (lunapark)GAUC 2017 Workshop App Tracking: Markus Vollmert (lunapark)
GAUC 2017 Workshop App Tracking: Markus Vollmert (lunapark)
 
Schnelle Winkel: 10x schnellere Webapps mit AngularJS und JEE
Schnelle Winkel: 10x schnellere Webapps mit AngularJS und JEESchnelle Winkel: 10x schnellere Webapps mit AngularJS und JEE
Schnelle Winkel: 10x schnellere Webapps mit AngularJS und JEE
 
Sencha Touch & PhoneGap
Sencha Touch & PhoneGapSencha Touch & PhoneGap
Sencha Touch & PhoneGap
 
Google Analytics & Seo @seosixt wiesn 2014
Google Analytics & Seo @seosixt wiesn 2014Google Analytics & Seo @seosixt wiesn 2014
Google Analytics & Seo @seosixt wiesn 2014
 
Einführung in die webOS Programmierung
Einführung in die webOS ProgrammierungEinführung in die webOS Programmierung
Einführung in die webOS Programmierung
 
Smartes SEO Monitoring & Alerting mit Apps Scripts [DE] - John Muñoz
Smartes SEO Monitoring & Alerting mit Apps Scripts [DE] - John MuñozSmartes SEO Monitoring & Alerting mit Apps Scripts [DE] - John Muñoz
Smartes SEO Monitoring & Alerting mit Apps Scripts [DE] - John Muñoz
 
Logstash: Windows und Linux Logmanagement (Webinar vom 07.11.2014)
Logstash: Windows und Linux Logmanagement (Webinar vom 07.11.2014)Logstash: Windows und Linux Logmanagement (Webinar vom 07.11.2014)
Logstash: Windows und Linux Logmanagement (Webinar vom 07.11.2014)
 
APEX 5.0, und sonst?
APEX 5.0, und sonst?APEX 5.0, und sonst?
APEX 5.0, und sonst?
 
Mobile Web Development from Scratch
Mobile Web Development from ScratchMobile Web Development from Scratch
Mobile Web Development from Scratch
 
Sencha Touch und PhoneGap
Sencha Touch und PhoneGapSencha Touch und PhoneGap
Sencha Touch und PhoneGap
 
Testing einer Angular App
Testing einer Angular AppTesting einer Angular App
Testing einer Angular App
 
Google Analytics Konferenz 2019_App Tracking_Runa Reno (Booking.com) & Markus...
Google Analytics Konferenz 2019_App Tracking_Runa Reno (Booking.com) & Markus...Google Analytics Konferenz 2019_App Tracking_Runa Reno (Booking.com) & Markus...
Google Analytics Konferenz 2019_App Tracking_Runa Reno (Booking.com) & Markus...
 
HTML5-Legacy-Anwendungen
HTML5-Legacy-AnwendungenHTML5-Legacy-Anwendungen
HTML5-Legacy-Anwendungen
 
Webinar - ABAP Development Tools
Webinar - ABAP Development ToolsWebinar - ABAP Development Tools
Webinar - ABAP Development Tools
 

Mehr von Stephan Hochdörfer

Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8
Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8
Stephan Hochdörfer
 
Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13
Stephan Hochdörfer
 
Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13
Stephan Hochdörfer
 
Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13
Stephan Hochdörfer
 
Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13
Stephan Hochdörfer
 
Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13
Stephan Hochdörfer
 
Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13
Stephan Hochdörfer
 
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Stephan Hochdörfer
 
Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Testing untestable code - ConFoo13
Testing untestable code - ConFoo13
Stephan Hochdörfer
 
A Phing fairy tale - ConFoo13
A Phing fairy tale - ConFoo13A Phing fairy tale - ConFoo13
A Phing fairy tale - ConFoo13
Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13
Stephan Hochdörfer
 
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Stephan Hochdörfer
 
Testing untestable code - IPC12
Testing untestable code - IPC12Testing untestable code - IPC12
Testing untestable code - IPC12
Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12
Stephan Hochdörfer
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012
Stephan Hochdörfer
 
Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12
Stephan Hochdörfer
 
Testing untestable code - oscon 2012
Testing untestable code - oscon 2012Testing untestable code - oscon 2012
Testing untestable code - oscon 2012
Stephan Hochdörfer
 
Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12
Stephan Hochdörfer
 

Mehr von Stephan Hochdörfer (20)

Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8
 
Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8
 
Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13
 
Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13
 
Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13
 
Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13
 
Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13
 
Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13
 
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
 
Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Testing untestable code - ConFoo13
Testing untestable code - ConFoo13
 
A Phing fairy tale - ConFoo13
A Phing fairy tale - ConFoo13A Phing fairy tale - ConFoo13
A Phing fairy tale - ConFoo13
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13
 
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12
 
Testing untestable code - IPC12
Testing untestable code - IPC12Testing untestable code - IPC12
Testing untestable code - IPC12
 
Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
 
Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012
 
Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12
 
Testing untestable code - oscon 2012
Testing untestable code - oscon 2012Testing untestable code - oscon 2012
Testing untestable code - oscon 2012
 
Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12
 

Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbstcampus13

  • 1. Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 Stephan Hochdörfer, bitExpert AG
  • 2. Offline. Na und? - Strategien für offlinefähige Applikationen Über mich  Stephan Hochdörfer  Head of IT der bitExpert AG, Mannheim  S.Hochdoerfer@bitExpert.de  @shochdoerfer
  • 3. Offline. Na und? - Strategien für offlinefähige Applikationen Daten auf dem Client speichern?
  • 4. Offline. Na und? - Strategien für offlinefähige Applikationen Wie wurde dies in der Vergangenheit gelöst?
  • 5. Offline. Na und? - Strategien für offlinefähige Applikationen Cookies. Lecker aber mehr auch nicht.
  • 6. Offline. Na und? - Strategien für offlinefähige Applikationen IE DHTML Behaviours
  • 7. Offline. Na und? - Strategien für offlinefähige Applikationen Flash Cookies schmecken auch lecker.
  • 8. Offline. Na und? - Strategien für offlinefähige Applikationen Google Gears mit neuem Ansatz.
  • 9. Gibt es nichts wirklich sinnvolles? Offline. Na und? - Strategien für offlinefähige Applikationen
  • 10. Offline. Na und? - Strategien für offlinefähige Applikationen als Lösung...
  • 11. Offline. Na und? - Strategien für offlinefähige Applikationen [...] we take the next step, announcing 2014 as the target for Recommendation. Jeff Jaffe, Chief Executive Officer, World Wide Web Consortium
  • 12. Offline. Na und? - Strategien für offlinefähige Applikationen
  • 13. Offline. Na und? - Strategien für offlinefähige Applikationen
  • 14. Was bedeutet „offline“? Offline. Na und? - Strategien für offlinefähige Applikationen
  • 15. Was bedeutet „offline“? Offline. Na und? - Strategien für offlinefähige Applikationen Applikation vs. Content
  • 16. Was bedeutet „offline“? Offline. Na und? - Strategien für offlinefähige Applikationen Application Cache vs. Offline Storage
  • 17. App Cache für statische Ressourcen Offline. Na und? - Strategien für offlinefähige Applikationen <!DOCTYPE html> <html lang="en"> HTML Page:
  • 18. <!DOCTYPE html> <html lang="en" manifest="cache.manifest"> App Cache für statische Ressourcen Offline. Na und? - Strategien für offlinefähige Applikationen HTML Page: cache.manifest (Content-Type: text/cache-manifest): CACHE MANIFEST js/app.js css/app.css favicon.ico http://someotherdomain.com/image.png
  • 19. App Cache für statische Ressourcen Offline. Na und? - Strategien für offlinefähige Applikationen CACHE MANIFEST # 2012-09-16 NETWORK: data.php CACHE: /main/home /main/app.js /settings/home /settings/app.js http://myhost/logo.png http://myhost/check.png http://myhost/cross.png
  • 20. App Cache für statische Ressourcen Offline. Na und? - Strategien für offlinefähige Applikationen CACHE MANIFEST # 2012-09-16 FALLBACK: / /offline.html NETWORK: *
  • 21. App Cache Scripting Offline. Na und? - Strategien für offlinefähige Applikationen // events fired by window.applicationCache window.applicationCache.onchecking = function(e) {log("Checking for updates");} window.applicationCache.onnoupdate = function(e) {log("No updates");} window.applicationCache.onupdateready = function(e) {log("Update ready");} window.applicationCache.onobsolete = function(e) {log("Obsolete");} window.applicationCache.ondownloading = function(e) {log("Downloading");} window.applicationCache.oncached = function(e) {log("Cached");} window.applicationCache.onerror = function(e) {log("Error");} // Log each file window.applicationCache.onprogress = function(e) { log("Progress: downloaded file " + counter); counter++; };
  • 22. App Cache Scripting Offline. Na und? - Strategien für offlinefähige Applikationen // Check if a new cache is available on page load. window.addEventListener('load', function(e) { window.applicationCache.addEventListener('updateready', function(e) { if(window.applicationCache.status == window.applicationCache.UPDATEREADY) { // Browser downloaded a new app cache. // Swap it in and reload the page window.applicationCache.swapCache(); if (confirm('New version is available. Load it?)) { window.location.reload(); } } else { // Manifest didn't change... } }, false); }, false);
  • 23. App Cache – Einige Fallstricke! Offline. Na und? - Strategien für offlinefähige Applikationen
  • 24. App Cache – Einige Fallstricke! Offline. Na und? - Strategien für offlinefähige Applikationen 1. Dateien werden immer(!) vom lokalen Cache ausgeliefert.
  • 25. App Cache – Einige Fallstricke! Offline. Na und? - Strategien für offlinefähige Applikationen 2. Der lokale Cache wird nur dann aktualisiert wenn sich die manifest Datei geändert hat.
  • 26. App Cache – Einige Fallstricke! Offline. Na und? - Strategien für offlinefähige Applikationen 3. Nicht ladbare Dateien aus der CACHE Sektion führen dazu dass der Cache invalide ist.
  • 27. App Cache – Einige Fallstricke! Offline. Na und? - Strategien für offlinefähige Applikationen 4. Kann die manifest Datei nicht geladen werden, erfolgt kein Caching!
  • 28. App Cache – Einige Fallstricke! Offline. Na und? - Strategien für offlinefähige Applikationen 5. Nicht gecachte Ressourcen werden auf einer gecachten Seite nicht angezeigt.
  • 29. App Cache – Einige Fallstricke! Offline. Na und? - Strategien für offlinefähige Applikationen 6. Nach Aktualisierung des Caches muss die Seite neu geladen werden!
  • 30. App Cache – Einige Fallstricke! Offline. Na und? - Strategien für offlinefähige Applikationen 7. Mit expires Header arbeiten um das Cachen des manifests zu verhinden!
  • 31. App Cache – Cache Manifest Validator Offline. Na und? - Strategien für offlinefähige Applikationen http://manifest-validator.com
  • 32. App Cache – Was darf gecacht werden? Offline. Na und? - Strategien für offlinefähige Applikationen
  • 33. App Cache – Was darf gecacht werden? Offline. Na und? - Strategien für offlinefähige Applikationen Ja:  Schriften  Startbild  Applikationsicon  Einstiegsseite  Fallbackseite Nein:  CSS  HTML  Javascript
  • 34. App Cache – Was darf gecacht werden? Offline. Na und? - Strategien für offlinefähige Applikationen Den App Cache nur für „statischen Content“ verwenden!
  • 35. Ausflug: Data URI Schema Offline. Na und? - Strategien für offlinefähige Applikationen
  • 37. Dynamische Daten lokal speichern... Offline. Na und? - Strategien für offlinefähige Applikationen
  • 38. Offline. Na und? - Strategien für offlinefähige Applikationen Beispiel: Todoliste
  • 39. Dynamische Daten lokal speichern... Offline. Na und? - Strategien für offlinefähige Applikationen Sourcen: github.com/bitExpert/html5-offline
  • 40. Dynamische Daten lokal speichern... Offline. Na und? - Strategien für offlinefähige Applikationen Web Storage, Web SQL Database, IndexedDB, File API
  • 41. Web Storage Offline. Na und? - Strategien für offlinefähige Applikationen
  • 42. Web Storage Offline. Na und? - Strategien für offlinefähige Applikationen Komfortable Art Daten offline zu speichern: Key/Value Speicher
  • 43. Web Storage: 2 Arten Offline. Na und? - Strategien für offlinefähige Applikationen localStorage vs. sessionStorage
  • 44. Web Storage: Datensatz hinzufügen Offline. Na und? - Strategien für offlinefähige Applikationen function add(item) { try { // for a new item set id if((typeof item.id === "undefined") || (null == item.id) || ("" == item.id)) { item.id = get_lastIndex() + 1; } // store object as string localStorage.setItem(item.id, JSON.stringify(item) ); // update the index set_lastIndex(item.id); } catch(ex) { console.log(ex); } }
  • 45. Web Storage: Datensatz ändern Offline. Na und? - Strategien für offlinefähige Applikationen function modify(item) { try { // store object as string localStorage.setItem(item.id, JSON.stringify(item) ); } catch(ex) { console.log(ex); } }
  • 46. Web Storage: Datensatz löschen Offline. Na und? - Strategien für offlinefähige Applikationen function remove (id) { try { localStorage.removeItem(id); } catch(ex) { console.log(ex); } }
  • 47. Web Storage: Datensätze auslesen Offline. Na und? - Strategien für offlinefähige Applikationen function read() { try { var lastIdx = get_lastIndex(); for(var i = 1; i <= lastIdx; i++) { if(null !== localStorage.getItem(i)) { // parse and render item var item = JSON.parse( localStorage.getItem(i) ); } } } catch(ex) { console.log(ex); } }
  • 48. Web Storage: Wie sessionStorage nutzen? Offline. Na und? - Strategien für offlinefähige ApplikationenOffline. Na und? - Strategien für offlinefähige Applikationen
  • 49. Web Storage: Wie sessionStorage nutzen? Offline. Na und? - Strategien für offlinefähige Applikationen Einfach: Ersetze „localStorage“ durch „sessionStorage“
  • 50. Web Storage: Datensatz hinzufügen Offline. Na und? - Strategien für offlinefähige Applikationen function add(item) { try { // for a new item set id if((typeof item.id === "undefined") || (null == item.id) || ("" == item.id)) { item.id = get_lastIndex() + 1; } // store object as string sessionStorage.setItem(item.id, JSON.stringify(item) ); // update the index set_lastIndex(item.id); } catch(ex) { console.log(ex); } }
  • 51. Web Storage: sessionStorage Fallstrick Offline. Na und? - Strategien für offlinefähige Applikationen Jedes Tab / Fenster bringt eigenen sessionStorage mit sich!
  • 52. Web Storage: Alternative Zugriffsmöglichkeiten Offline. Na und? - Strategien für offlinefähige Applikationen var value = "my value"; // method call localStorage.setItem("key", value); // Array accessor localStorage[key] = value; // Property accessor localStorage.key = value;
  • 53. Offline. Na und? - Strategien für offlinefähige Applikationen Welche Daten sind gespeichert?
  • 54. Web Storage: Vorteile Offline. Na und? - Strategien für offlinefähige Applikationen Die meisten der aktuellen Browser „können“ Web Storage.
  • 55. Web Storage: Vorteile Offline. Na und? - Strategien für offlinefähige Applikationen Funktioniert sogar im IE8 :)
  • 56. Web Storage: Vorteile Offline. Na und? - Strategien für offlinefähige Applikationen Kein HTTP Overhead wie bsp. bei Cookies.
  • 57. Web Storage: Nachteile Offline. Na und? - Strategien für offlinefähige Applikationen Daten werden unstrukturiert gespeichert.
  • 58. Web Storage: Nachteile Offline. Na und? - Strategien für offlinefähige Applikationen Nicht transaktionsfähig!
  • 59. Web Storage: Nachteile Offline. Na und? - Strategien für offlinefähige Applikationen Nicht asynchron!
  • 60. Web Storage: Nachteile Offline. Na und? - Strategien für offlinefähige Applikationen Daten können nicht automatisch verfallen. Manueller Aufwand nötig.
  • 61. Web Storage: Nachteile Offline. Na und? - Strategien für offlinefähige Applikationen Unzureichende Informationen wie voll der lokale Cache wirklich ist.
  • 62. Web Storage: Nachteile Offline. Na und? - Strategien für offlinefähige Applikationen http:// und https:// definieren unterschiedliche Storages.
  • 63. Web SQL Database Offline. Na und? - Strategien für offlinefähige Applikationen
  • 64. Web SQL Database Offline. Na und? - Strategien für offlinefähige Applikationen Eine lokale SQL Datenbank auf SQLite Basis.
  • 65. Web SQL Database: Callbacks Offline. Na und? - Strategien für offlinefähige Applikationen var onError = function(tx, ex) { alert("Error: " + ex.message); }; var onSuccess = function(tx, results) { var len = results.rows.length; for(var i = 0; i < len; i++) { // render found todo item render(results.rows.item(i)); } };
  • 66. Web SQL Database: Datenbank erzeugen Offline. Na und? - Strategien für offlinefähige Applikationen // initalize the database connection var db = openDatabase('todo', '1.0', 'Todo Database', 5 * 1024 * 1024 ); db.transaction(function (tx) { tx.executeSql( 'CREATE TABLE IF NOT EXISTS todo '+ '(id INTEGER PRIMARY KEY ASC, todo TEXT)', [], onSuccess, onError ); });
  • 67. Web SQL Database: Datenbankmigration Offline. Na und? - Strategien für offlinefähige Applikationen function m1(t){ t.executeSql("create table tbl1...") } function m2(t){ t.executeSql("alter table tbl1...") } function m3(t){ t.executeSql("alter table tbl1...") } if(db.version == "") { db.changeVersion("", "1", m1, null, function() { db.changeVersion("1", "2", m2, null, function() { db.changeVersion("2", "3", m3); }); }); } if(db.version == "1") { db.changeVersion("1", "2", m2, null, function() { db.changeVersion("2", "3", m3); }); } if(db.version == "2") { db.changeVersion("2", "3", m3); }
  • 68. Web SQL Database: Datensatz hinzufügen Offline. Na und? - Strategien für offlinefähige Applikationen function add(item) { db.transaction(function(tx) { tx.executeSql( 'INSERT INTO todo (todo) VALUES (?)', [ item.todo ], onSuccess, onError ); }); }
  • 69. Web SQL Database: Datensatz verändern Offline. Na und? - Strategien für offlinefähige Applikationen function modify(item) { db.transaction(function(tx) { tx.executeSql( 'UPDATE todo SET todo = ? WHERE id = ?', [ item.todo item.id ], onSuccess, onError ); }); }
  • 70. Web SQL Database: Datensatz löschen Offline. Na und? - Strategien für offlinefähige Applikationen function remove(id) { db.transaction(function (tx) { tx.executeSql( 'DELETE FROM todo WHERE id = ?', [ id ], onSuccess, onError ); }); }
  • 71. Web SQL Database: Datensätze auslesen Offline. Na und? - Strategien für offlinefähige Applikationen function read() { db.transaction(function (tx) { tx.executeSql( 'SELECT * FROM todo', [], onSuccess, onError ); }); }
  • 72. Web SQL Database: Vorteile Offline. Na und? - Strategien für offlinefähige Applikationen Eine SQL Datenbank im Browser!
  • 73. Web SQL Database: Nachteile Offline. Na und? - Strategien für offlinefähige Applikationen Eine SQL Datenbank im Browser!
  • 74. Web SQL Database: Nachteile Offline. Na und? - Strategien für offlinefähige Applikationen SQLite kann seeeehr langsam sein!
  • 75. Web SQL Database: Nachteile Offline. Na und? - Strategien für offlinefähige Applikationen Nicht länger Teil der HTML5 Spezifikation!
  • 76. IndexedDB Offline. Na und? - Strategien für offlinefähige Applikationen
  • 77. IndexedDB Offline. Na und? - Strategien für offlinefähige Applikationen Kompromiss aus Web Storage und Web SQL Database.
  • 78. IndexedDB Offline. Na und? - Strategien für offlinefähige Applikationen Die NoSQL Datenbank für den Browser.
  • 79. Web SQL Database vs. IndexedDB Offline. Na und? - Strategien für offlinefähige Applikationen Kategorie Web SQL IndexedDB Speicherart Tabellen mit Spalten und Zeilen Objectstore mit Javascript Objekten und Keys Abfrage mechanismus SQL Cursor APIs, Key Range APIs und Applicationslogik Transaktionali tät Lock für Databanken, Tabellen oder Zeilen bei READ_WRITE Transaktionen Locks für Datenbanken (VERSION_CHANGE Transaktion) und Objectstores (READ_ONLY, READ_WRITE Transaktion). Transaktions- Commits Transaktionen werden explizt erzeugt. Standard: Rollback, außer es wird explizit ein commit ausgeführt. Transaktionen werden explizt erzeugt. Standard: Committen sofern kein Fehler aufgetreten ist.
  • 80. IndexedDB: Vorarbeiten Offline. Na und? - Strategien für offlinefähige Applikationen // different browsers, different naming conventions var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB; var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction; var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
  • 81. IndexedDB: Objektspeicher erzeugen Offline. Na und? - Strategien für offlinefähige Applikationen var db = null; var request = indexedDB.open("todo"); request.onfailure = onError; request.onsuccess = function(e) { db = request.result; var v = "1.0"; if(v != db.version) { var verRequest = db.setVersion(v); verRequest.onfailure = onError; verRequest.onsuccess = function(e) { var store = db.createObjectStore( "todo", { keyPath: "id", autoIncrement: true } ); e.target.transaction.oncomplete = function() {}; }; } };
  • 82. IndexedDB: Datensatz hinzufügen Offline. Na und? - Strategien für offlinefähige Applikationen function add(item) { try { var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE); var store = trans.objectStore("todo"); var request = store.put({ "todo": item.todo, }); } catch(ex) { onError(ex); } }
  • 83. IndexedDB: Datensatz verändern Offline. Na und? - Strategien für offlinefähige Applikationen function modify(item) { try { var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE); var store = trans.objectStore("todo"); var request = store.put(item); } catch(ex) { onError(ex); } }
  • 84. IndexedDB: Datensatz löschen Offline. Na und? - Strategien für offlinefähige Applikationen function remove(id) { try { var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE); var store = trans.objectStore("todo"); var request = store.delete(id); } catch(ex) { onError(ex); } }
  • 85. IndexedDB: Datensätze auslesen Offline. Na und? - Strategien für offlinefähige Applikationen function read () { try { var trans = db.transaction(["todo"], IDBTransaction.READ); var store = trans.objectStore("todo"); var keyRange = IDBKeyRange.lowerBound(0); var cursorRequest = store.openCursor(keyRange); cursorRequest.onsuccess = function(e) { var result = e.target.result; if(!!result == false) { return; } // @TODO: render result.value result.continue(); }; } catch(ex) { onError(ex); } }
  • 86. IndexedDB: Datensatz mittels Index auslesen Offline. Na und? - Strategien für offlinefähige Applikationen try { var index = db.openIndex('todo'); var item = index.get(1337); } catch(ex) { onError(ex); }
  • 87. IndexedDB: Index erzeugen Offline. Na und? - Strategien für offlinefähige Applikationen try { // create non-unique index db.createIndex("Created", "createdDate", {"unique": false}); // create unique index db.createIndex("OtherKey", "otherField", {"unique": true}); // create multi-column index (not working in IE10!) db.createIndex("MultiIndex", ["field1", "field2"]); } catch(ex) { onError(ex); }
  • 88. IndexedDB: Zu kompliziert? Offline. Na und? - Strategien für offlinefähige Applikationen
  • 89. IndexedDB: Zu kompliziert? Offline. Na und? - Strategien für offlinefähige Applikationen db.js als Wrapper nutzen
  • 90. IndexedDB: db.js als Wrapper Offline. Na und? - Strategien für offlinefähige Applikationen var server; db.open( { server: 'todo', version: 1, schema: { todo: { key: { keyPath: 'id' , autoIncrement: true}, indexes: { Created: { } } } } }).done(function(s) { server = s; });
  • 91. IndexedDB: db.js als Wrapper Offline. Na und? - Strategien für offlinefähige Applikationen server.todo.add( { todo: 'This is a sample todo item' }).done(function(item) { // item stored });
  • 92. IndexedDB: db.js als Wrapper Offline. Na und? - Strategien für offlinefähige Applikationen server.todo.query() .execute() .done(function(results) { // do something with the results });
  • 93. IndexedDB: Vorteile Offline. Na und? - Strategien für offlinefähige Applikationen Neuer Standard der künftig durch viele Browser unterstützt wird.
  • 94. IndexedDB: Nachteile Offline. Na und? - Strategien für offlinefähige Applikationen Nicht alle mobilen Browser untersützen IndexedDB.
  • 95. IndexedDB Polyfill Offline. Na und? - Strategien für offlinefähige Applikationen IndexedDB Emulation via WebSQL: http://nparashuram.com/IndexedDBShim
  • 96. File API Offline. Na und? - Strategien für offlinefähige Applikationen
  • 97. File API Offline. Na und? - Strategien für offlinefähige Applikationen FileReader API und FileWriter API
  • 98. File API: Vorarbeiten Offline. Na und? - Strategien für offlinefähige Applikationen var onError = function(e) { var msg = ''; switch(e.code) { case FileError.QUOTA_EXCEEDED_ERR: msg = 'QUOTA_EXCEEDED_ERR'; break; case FileError.NOT_FOUND_ERR: msg = 'NOT_FOUND_ERR'; break; case FileError.SECURITY_ERR: msg = 'SECURITY_ERR'; break; case FileError.INVALID_MODIFICATION_ERR: msg = 'INVALID_MODIFICATION_ERR'; break; case FileError.INVALID_STATE_ERR: msg = 'INVALID_STATE_ERR'; break; default: msg = 'Unknown Error'; break; }; alert("Error: " + msg); };
  • 99. File API: Vorarbeiten II Offline. Na und? - Strategien für offlinefähige Applikationen // File system has been prefixed as of Google Chrome 12 window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder; var size = 5 * 1024*1024; // 5MB
  • 100. File API: Quota anfordern Offline. Na und? - Strategien für offlinefähige Applikationen // request quota for persistent store window.webkitStorageInfo.requestQuota( PERSISTENT, size, function(grantedBytes) { window.requestFileSystem( PERSISTENT, grantedBytes, function(fs) { // @TODO: access filesystem } } } }
  • 101. Offline. Na und? - Strategien für offlinefähige Applikationen
  • 102. File API: Daten hinzufügen Offline. Na und? - Strategien für offlinefähige Applikationen function add(item) { window.webkitStorageInfo.requestQuota( PERSISTENT, size, function(grantedBytes) { window.requestFileSystem( PERSISTENT, grantedBytes, function(fs){ writeToFile(fs, item); }, onError ); }, function(e) { onError(e); } ); }
  • 103. File API: Daten hinzufügen II Offline. Na und? - Strategien für offlinefähige Applikationen function writeToFile(fs, item) { fs.root.getFile( 'todo.txt', { create: true }, function(fileEntry) { fileEntry.createWriter( function(fileWriter) { var bb = new window.BlobBuilder(); bb.append(JSON.stringify(item)+ "n"); fileWriter.seek(fileWriter.length); fileWriter.write( bb.getBlob('text/plain')); }, onError ); }, onError ); }
  • 104. File API: Daten hinzufügen II Offline. Na und? - Strategien für offlinefähige Applikationen function writeToFile(fs, item) { fs.root.getFile( 'todo.txt', { create: true }, function(fileEntry) { fileEntry.createWriter( function(fileWriter) { var bb = new window.BlobBuilder(); bb.append(JSON.stringify(item)+ "n"); fileWriter.seek(fileWriter.length); fileWriter.write( bb.getBlob('text/plain')); }, onError ); }, onError ); } Deprecated!
  • 105. File API: Daten hinzufügen II Offline. Na und? - Strategien für offlinefähige Applikationen function writeToFile(fs, item) { fs.root.getFile( 'todo.txt', { create: true }, function(fileEntry) { fileEntry.createWriter( function(fileWriter) { var blob = new Blob([ JSON.stringify(item)+"n" ]); fileWriter.seek(fileWriter.length); fileWriter.write(blob); }, onError ); }, onError ); }
  • 106. File API: Daten auslesen Offline. Na und? - Strategien für offlinefähige Applikationen function read() { window.webkitStorageInfo.requestQuota( PERSISTENT, size, function(grantedBytes) { window.requestFileSystem( PERSISTENT, grantedBytes, function(fs){ readFromFile(fs); }, onError ); }, function(e) { onError(e); } ); }
  • 107. File API: Daten auslesen II Offline. Na und? - Strategien für offlinefähige Applikationen function readFromFile(fs) { fs.root.getFile( 'todo.txt', { create: true }, function(fileEntry) { fileEntry.file(function(file){ var reader = new FileReader(); reader.onloadend = function(e) { if (evt.target.readyState == FileReader.DONE) { // process this.result } }; reader.readAsText(file); }); }, onError ); }
  • 108. Bin ich online? Offline. Na und? - Strategien für offlinefähige Applikationen
  • 109. Bin ich online? Offline. Na und? - Strategien für offlinefähige Applikationen document.body.addEventListener("online", function () { // browser is online! } document.body.addEventListener("offline", function () { // browser is not online! }
  • 110. Bin ich online? Andere Vorgehensweise... Offline. Na und? - Strategien für offlinefähige Applikationen $.ajax({ dataType: 'json', url: 'http://myappurl.com/ping', success: function(data){ // ping worked }, error: function() { // ping failed -> Server not reachable } });
  • 111. Datensynchronisation Offline. Na und? - Strategien für offlinefähige Applikationen
  • 112. Datensynchronisation Offline. Na und? - Strategien für offlinefähige Applikationen PouchDB, the JavaScript Database that syncs!
  • 113. Datensynchronisation Offline. Na und? - Strategien für offlinefähige Applikationen var db = new PouchDB('todo'); db.put({ _id: 1, todo: 'Get some work done...', }); db.replicate.to('http://example.com/mydb');
  • 114. NoBackend Bewegung Offline. Na und? - Strategien für offlinefähige Applikationen
  • 115. NoBackend Bewegung Offline. Na und? - Strategien für offlinefähige Applikationen Entkopplung von Frontend und Backend!
  • 116. NoBackend Bewegung: Hood.ie Offline. Na und? - Strategien für offlinefähige Applikationen „Hoodie is an architecture for frontend-only web apps“
  • 117. Browserunterstützung? Offline. Na und? - Strategien für offlinefähige Applikationen
  • 118. Browserunterstützung? Offline. Na und? - Strategien für offlinefähige Applikationen App Cache Web Storage WebSQL IndexedDB File API Data URI IE 10.0 8.0 10.0 10.0 - 8.0* Firefox 11.0 11.0 11.0 11.0 19.0 16.0 Chrome 18.0 18.0 18.0 18.0 18.0 18.0 Safari 5.1 5.1 5.1 - - 5.1 Opera 12.1 12.1 12.1 - - 12.1 iOS Safari 3.2 3.2 3.2 - - 3.2 Android 2.1 2.1 2.1 - - 2.1 Quelle: http://caniuse.com
  • 119. Speicherplatzbeschränkung? Offline. Na und? - Strategien für offlinefähige Applikationen
  • 120. Speicherplatzbeschränkung? Offline. Na und? - Strategien für offlinefähige Applikationen Alle vorgestellten Technologien sind durch Quotas beschränkt.
  • 121. Speicherplatzbeschränkung? Offline. Na und? - Strategien für offlinefähige Applikationen App Cache Web Storage WebSQL IndexedDB File API iOS 5.1 10 MB 5 MB 5 MB 5 MB Android 4 unlimited 5 MB ? ? Safari 5.2 unlimited 5 MB 5 MB 5 MB Chrome 18 5 MB 5 MB unlimited unlimited unlimited IE 10 50 MB 10 MB 500 MB 500 MB Opera 11 50 MB 5 MB 5 MB 5 MB Firefox 11 unlimited 10 MB 50 MB 50 MB Minimumwerte, je nach Konfiguration ist mehr möglich.