WebAssembly in Action

Author of the book "WebAssembly in Action"
Save 40% with the code: ggallantbl
The book's original source code can be downloaded from the Manning website and GitHub. The GitHub repository includes an updated-code branch that has been adjusted to work with the latest version of Emscripten (currently version 3.1.44).

Thursday, July 22, 2010

HTML 5 - Web Storage


To avoid any confusion, HTML 5 Web Storage is not the IndexedDB API which is also an HTML 5 related feature that most browsers now support.

HTML 5 Web Storage is a form of browser storage that is similar to cookies but with several advantages.


Storage Size

Cookies allow you to store a small amount of data (maximum of 4 KB per cookie) in the browser. For most web sites this is more than enough room and not enough reason to switch storage mechanisms. If your web site/web application has a need for more than 4 KB of space for storage in the browser then web storage might be an option for you.

The W3C specification for web storage allows each browser to determine how much storage space to allow by default but suggests a minimum of 5 MB. The specification also indicates that the browser is permitted to prompt the user to increase the storage space if more is needed.

Web storage in Internet Explorer is reported to be 10 MB while other browsers, like Firefox and Opera, have the size set to 5 MB.


Network Latency

Another downside to cookies is that they are passed back-and-forth with every web request. Having this data available on the server-side is sometimes handy but one can work around not having this data using other means (URL/Post parameters, AJAX request, etc).

For the most part, cookies are passed back-and-forth between the browser and the server and are never even used by the server-side code. They simply add to the bandwidth needed and cause the web requests to slow down because they need to transmit more data.

Web storage, on the other hand, is local to the browser and is not passed back-and-forth to the server. This results in faster web requests because less data needs to be passed around.


Browser Support

One of the nicest things about web storage is that it is already available in most browsers including Internet Explorer 8.

For the most part, the functionality, of the web storage objects, is very similar in all browsers with the exception of the storage event in Internet Explorer compared to the other major browsers. The storage event is discussed later in this post.


Web Storage Object Types

There are two types of web storage objects that sit within the window object called sessionStorage and localStorage.

The web storage objects are basically a list of key/value pairs.


Test for browser features

Before we dig too far into web storage it is important to remember that even though web storage is included in the latest release of all major browsers, it is not necessarily in older browsers that might be used when visiting your site or using your web application.

When using a feature that is not in older browsers, it is very important to test if the feature exists first before trying to use it. Otherwise, someone visiting your web site might not have a very pleasant time due to JavaScript errors or things just not working.

Testing to see if the web storage objects exist will tell you if the browser supports that particular functionality. In this case, since there are two different storage objects, it's best to test for their existence separately as in the following example:

// Check if the sessionStorage object exists
if (window.sessionStorage) {
g_bBrowserSupportsSessionStorage = true;
}

// Check if the localStorage object exists
if (window.localStorage) {
g_bBrowserSupportsLocalStorage = true;
}


Differences between sessionStorage and localStorage

Each window/tab gets its own copy of a sessionStorage object which allows for the storage of key/value pairs that are specific to the current window.

One thing to note about sessionStorage objects is that if you open a window from the current window, the sessionStorage object that is created for the new window is a clone of the sessionStorage object of the window that opened it. The sessionStorage objects are no longer in sync after the new window has been opened but this is something to be mindful of if you find values in the new window's sessionStorage object that you were not expecting.

With localStorage, each origin (SomeFreeWebSiteHost.com for example) gets a single copy of a localStorage object that is shared by all windows/tabs from that origin. This has the advantage that multiple windows of your web site/web application can easily share data but that ease of sharing could result in security concerns if you are not aware of how this object is shared.

The sessionStorage key/value pairs exist only while the browser is open. The moment you close the browser, the sessionStorage key/value pairs for your window are cleared.

With localStorage, the key/value pairs stick around even if the browser is closed and re-opened.


Web Storage Object - Methods and Properties

Both types of web storage share the same functions and properties:
  • setItem(Key, Value)
  • getItem(Key)
  • removeItem(Key)
  • clear()
  • key(iIndex)
  • length

setItem adds the key/value pair to the storage object if the key doesn't already exist in the storage object. If the key already exists in the storage object, the value is simply updated.

getItem returns the value from the storage object for the key specified. If the key does not exist in the storage object, null is returned.

removeItem removes the item specified from the storage object.

clear removes all items from the storage object

key returns the name of the item at the zero-based index specified. Returns null if the index doesn't exist.

length returns a number indicating how many key/value pairs are in the storage object


Shorthand methods

Since web storage is implemented in JavaScript, there are shorthand methods that can be used instead of calling setItem or getItem directly.

The following examples are all using the sessionStorage object but you can swap that for localStorage and they will still work.

The following examples are different ways that one could call setItem on the sessionStorage object:

// The method outlined in the W3C spec
window.sessionStorage.setItem("OurKey", "Some Value");

// Using array notation
window.sessionStorage["OurKey"] = "Some Value";

// Using dot notation
window.sessionStorage.OurKey = "Some Value";

The following examples are different ways that one could call getItem on the sessionStorage object:

// The method outlined in the W3C spec
var sValue = window.sessionStorage.getItem("OurKey");

// Using array notation
var sValue = window.sessionStorage["OurKey"];

// Using dot notation
var sValue = window.sessionStorage.OurKey;

The following are examples of ways to remove items from the sessionStorage object:

// Remove a single item using the method outlined in the W3C spec
window.sessionStorage.removeItem("OurKey");

// Remove a single item using the delete keyword (same as above, just
// with a different syntax)

delete window.sessionStorage["OurKey"];

// Remove all items
window.sessionStorage.clear();


Storage Events

According to the W3C specification on web storage, whenever a storage object is modified (setItem, removeItem for example) a 'storage' event is to be passed to all windows that the modification applies to.

The storage event does not bubble and cannot be canceled.

When you modify the sessionStorage object, the modification only applies to the current window. The weird thing is that only Internet Explorer 8 (and IE 9 Preview 3) receives a storage event call when the sessionStorage object is modified.

When you modify the localStorage object, the modification applies to all windows/tabs of that window's origin and as a result, other windows that happen to be open from the same origin will receive the event too.


Attaching to the Storage Event

Internet Explorer 8 implements the storage event differently than all other browsers, including IE 9 Preview 3, in that the event is passed to the document object rather than the window object. This difference might be due to the fact that the Web Storage specification is still a work in progress and Internet Explorer may have implemented the feature only to have the specification change to the window object (this is just a guess as to what might have happened - I really don't know but I'm giving Microsoft the benefit of the doubt here).

Getting around the Internet Explorer 8 storage event issue described above isn't too hard since Internet Explorer 9 Preview 3 now supports addEventListener. The following is an example of attaching to the 'storage' event that will also work with IE 8:

// Add the event listener (W3C browsers, including IE 9,
// use addEventListener)

if (window.addEventListener) {
// Listen for the storage event (triggered when the storage is
// modified - setItem, removeItem, clear)

window.addEventListener("storage", OurStorageListener, true);
}
else if (window.attachEvent) { // IE 8 and previous...
// Listen for the storage event on the DOM object
document.attachEvent("onstorage", OurStorageListener);
}

The above example might not be the best approach if other, non-IE browsers, also have the attachEvent method.


Receiving the Storage Event

Receiving the storage event is quite straightforward once you've attached to the event. All you need is a function that receives the event parameter as in the following example:

function OurStorageListener(e) {
// Take the event details and put it into a string
var sValue = ("Key: " + e.key +
" ...New Value: " + e.newValue +
" ...Old Value: " + e.oldValue +
" ...URL: " + e.url +
" ...Storage Area: " + e.storageArea);

// Display the event details to the screen
document.getElementById("divResults2").innerHTML = sValue;
}

This event will be called by all browsers that implement the 'storage' event when the storage object is modified if that object also applies to the window that has registered for the event.

I mentioned this earlier but I'll mention this again just in case, modifications to the sessionStorage object currently only trigger the storage event in Internet Explorer 8 and 9 Preview 3. The event is not currently triggered by any other browser from what I can tell even though the W3C specification seems to indicate that it should be triggered even for the sessionStorage object.

One thing to note about the above example is that not all browsers that support the storage event actually support all the storage event properties. Internet Explorer 8, for example, only supports the url property.

In the browsers that do support the storage event properties the following properties are available:

key is the key being changed. In our examples above this would be 'OurKey'. This will be null if the event was a result of the clear function being called on the storage object.

newValue is the value specified if a setItem call was made. If a removeItem call was made, this value will be null. This property will also be null if the clear function was called on the storage object.

oldValue is the old value if the key already existed when setItem was called. If setItem was called and the item did not already exist, this value will be null. This property will also be null if the clear function was called on the storage object.

url is the address of the document who's storage object was affected

storageArea represents the storage object that was affected (a reference to the storage object that was modified to give you easier access to the values within the object as well as the ability to modify items if need be). This way you don't have to guess if it was a session or a local storage object that was modified since you have direct access to the object that was modified.


Some closing thoughts on Web Storage

According to the W3C specification on web storage, there is a suggestion that web browsers can optionally have the web storage functionality turned off (perhaps as a security feature and only on for white listed sites). If you try to access a storage object when web storage is off, an exception could be raised.

There is also the possibility, if your web site/web application is storing a large amount of data that you will exceed the limit given by the browser for your window/origin. This limit is quite high (5 MB in most cases and 10 MB for Internet Explorer) but, if it is hit, it may result in an exception being thrown as well.

For more detailed information on the HTML 5 Web Storage specification you can view it by clicking on the following link:
http://www.w3.org/TR/webstorage/

No comments:

Post a Comment