Programming the Mobile Web : HTML 5 (part 4) - Client Storage

1/24/2011 4:28:02 PM

7. Client Storage

Working offline is great, but there’s a problem: where should a web application store vital statistics and other information when the device is not connected to the Internet? And if the device is not connected to the Internet, how can our applications access helpful databases or information? Client storage solutions come to our assistance, in two flavors: key/value storage and SQL databases (yes, from JavaScript, without server interaction).

Of course, we also have cookies, but they are simpler (only string storage), and we know they are not guaranteed to survive in the browser.

7.1. Key/value storage

HTML 5 defines a key/value store through two objects: localStorage and sessionStorage. They are pretty much the same, but the scopes are different: while the local store is used for long-term storage, the session store doesn’t persist after the user closes the tab or window.


We should use try/catch blocks when saving items, in case problems occur with the storage or the maximum available space is exceeded.

Both stores are used in the same way:

// Save an object or variable in the store
localStorage.setItem("name_in_the_storage", object_to_store);

// Read an object from the store
var object = localStorage.getItem("name_in_the_storage");

We can also delete all the objects using clear or delete one key using removeItem. There is also a storage event that we can listen for with window.addEventListener that will be fired when the contents of the local or session stores have changed.

7.2. SQL database

Having a relational database available in JavaScript sounds powerful. The main method that defines the availability of the JavaScript SQL database is the window.openDatabase method. This method has the following signature:

var db = window.openDatabase(shortName, version, displayName, sizeExpectable);

If we use a try/catch, we can capture errors during the operation. This method opens the database if it exists and creates it if it is the first time we’ve used it. To execute non-recordset sentences (CREATE TABLE, INSERT, etc.) we can use a transaction using the transact method, which receives a function as parameter. As a transaction, if one sentence fails, the others will not execute:
db.transact(function(t)) {
AUTOINCREMENT, name TEXT NOT NULL)', [], function() {}, errorHandler);

The array parameter after the query string is an array of parameters to be replaced in the query (using ? inside), the next parameter is the data handler function (not used in a non-recordset query), and the last parameter is a function handler for errors in the query.


HTML 5 doesn’t define which database engine should be used. Mobile browsers use SQLite, the open source database engine, so check the SQLite documentation for data type and SQL syntax support.

To create a typical SELECT statement with recordset looping, we can use the following template:

db.transact(function(t)) {
t.executeSql('SELECT * FROM countries', [], countriesHandler, errorHandler);

function countriesHandler(transaction, data) {
var record;
var id;
var name;
for (var i=0; i<data.rows.length; i++) {
// We get the current record
record = data.rows[i];
id = record['id'];
name = record['name'];
// Do something with record information

function errorHandler(transaction, error) {
alert('Error getting results');


JavaScript databases support versioning, allowing us to change schema on newer versions of our applications and detect what the current version installed on the client is, to create a migration procedure.

If you were working offline you should implement a synchronization method, using Ajax to download changes from and upload them to the server.


Safari on iOS accepts up to 5 MB in offline storage without user intervention. If you try to save more than 5 MB, the user will need to approve it (an automatic alert will appear).

7.2.1. Gears storage

Google Gears ( is an open source project that enhances web browsers and JavaScript with more functionality, much of which is part of the HTML 5 draft. Android 1.X supports only Gears, and we can also use SQL databases with Gears. The normal usage is simple and synchronous, as the following sample demonstrates:

<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript">
var db = google.gears.factory.create('beta.database');'countries');
name TEXT NOT NULL)');

var rs = db.execute('SELECT * FROM countries');

while (rs.isValidRow()) {
var id = rs.field(0);
var name = rs.field(1));
// Do something;

Fortunately, Google is working on an open source project that gives us an abstraction layer for both HTML 5 databases and Gears databases using the same code. The project is called the Web Storage Portability Layer and it is available at


Safari on iOS allows you to view stored databases and delete them from the device using SettingsSafariDatabases.

With this new layer, we can use the following code for select queries in both frameworks:

var database = google.wspl.DatabaseFactory.createDatabase('countries',
var statement = google.wspl.Statement('SELECT * FROM countries;');

database.createTransaction(function(tx) {
tx.executeAll([statement], {onSuccess: function(tx, resultSet) {
// Statement succeeded

for(; resultSet.isValidRow(); {
var id = resultSet.getRow()['id'];
var name = resultSet.getRow()['name'];
}, onFailure: function(error) {
// Statement failed
}, {onSuccess: function() {
// After transaction commits, before any other starts
}, onFailure: function(error) {
// After transaction fails, before any other starts

7.3. Client JSON store

Prepared for mobile devices, Lawnchair is a local client JSON store that uses HTML 5 features behind a very simple API. You can download the library from

To create a store, we just use code like this:

var countries = new Lawnhair('countries');

Then, we can save an object synchronously:{id: 5, name: 'Spain'});
// Object saved

or asynchronously:{id: 5, name: 'Spain'}, function() {
// Object saved

We can also save it using a key/value mechanism for easy retrieval:{key: 5, value: 'Spain'});

var spain = countries.get(5);

And we can easily get all the documents using:

countries.all(function(country) {
// We receive every country in this function

We can also remove documents, clear all the storage, and create iterators for easy filtering.

Web Compatibility Test

In 2010, the W3C created a test to score mobile browsers in terms of their RIA, Ajax, and HTML 5 support. The Web Compatibility Test for Mobile Browsers, available at, verifies compatibility with Ajax, the canvas HTML tag, the contenteditablevideo and audio HTML 5 tags, Web Workers, local storage, session storage, and @font-face. There are currently no mobile browsers that score 100%. attribute, geolocation, HTML 5 input forms, the offline AppCache, the

Some results are:

  • iPhone 3.0: 83%

  • Firefox 3.5 for Maemo: 83%

  • Bada Browser: 75%

  • Android 1.6–2.1: 67%

  • Opera: 33%

  • Symbian 5th edition: 17%

  • webOS: 17%

  • NetFront 3.5: 8.33%

  •  Windows Phone 7 : Submitting Your First Windows Phone Application to the Windows Phone Marketplace
  •  Windows Phone 7 : Packaging, Publishing, and Managing Applications
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 3)
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 2)
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 1)
  •  Programming the Mobile Web : Mobile Rich Internet Applications (part 2) - JavaScript Mobile UI Patterns
  •  Programming the Mobile Web : Mobile Rich Internet Applications (part 1) - JavaScript UI Libraries
  •  Windows Mobile Security - Kernel Architecture
  •  Windows Mobile Security - Introduction to the Platform
  •  iPhone Programming : Table-View-Based Applications - Building a Model
    Most View
    SharePoint 2010: Architecture Fundamentals - Understanding SharePoint Administration
    Western Digital Black 4TB - One Of The Quickest Physical Drives
    Group Test: Integrated Valve Amps $2,175-$3,000 (Part 2)
    Web Security : Attacking AJAX - Checking for Cross-Domain Access, Reading Private Data via JSON Hijacking
    SharePoint 2010: Architecture Fundamentals - SharePoint Lists, Libraries, and Items, Pages, Navigation
    Mouse And Keyboard Buyer’s Guide - Dual Wielding (Part 2)
    Where It Meets Lifestyle – November 2012 (Part 2)
    How To Deploy A Wireless Network In Your School
    Routers - March 2014 (Part 2) - Asus RT-AC68U, Tenda W1800R
    MasterClass: How To Automate Your Life (Part 4)
    Top 10
    Evasive Motorsports’ ’04 S2000 – Evasive S2k V.2 (Part 2)
    Evasive Motorsports’ ’04 S2000 – Evasive S2k V.2 (Part 1)
    Focus ST – Speed Demon (Part 3)
    Focus ST – Speed Demon (Part 2)
    Focus ST – Speed Demon (Part 1)
    Cyrus Lyric 09 System Review (Part 2)
    Cyrus Lyric 09 System Review (Part 1)
    HD/SD Meter Revez HD-TSF Review
    Integrated Amplifier KR Audio VA880 Review (Part 2)
    Integrated Amplifier KR Audio VA880 Review (Part 1)