Aug
26
2009

Developing Client-Side Persistence

Problog

This post cover the following topics:

  • Why do we need client side persistence
  • Using the cookie in javascript
  • Writing javascript object to the cookie using JSON
  • The Cookie Monster object to handle client side persistence
  • Alternatives to the cookie

As web technology evolves we started to notice more and more advanced web applications that are more similar in their characteristics to regular desktop application.  While in desktop application the client-side persistence has a diverse range of choices, such as registry, databases and access to local files, web applications are much more restricted in that sense.

While there are a few mechanisms that allows web applications to store and load data locally, the most common one is through cookies.   In javascript the document object has a properly named cookie. While this property seems to be a simple string value, it is much more than that. It allows web application to store and load data from the hard-drive, and with a little bit of manipulations and wrappers we can simulate a local persistence mechanism.

But first, let’s explore the javascript cookie.

Become a Cookie Master

Used with permission

Usually a cookie is associated with a particular web page or a web site, and it’s
a small amount of data stored by the web browser. Cookies are not only used for client purposes, but also function for server-side scripting and are a standard extension to the HTTP protocol. In fact, cookies were designed to enable server-side programming with a local access to data – usually to store and read user preferences or login information.

Javascript allow us to create, delete, modify and read cookies using the

cookie property in the document object.

Cookie Lifespan

Cookies are short-lived by default; the data that it saves last until the user closes the browser. Well, that’s no good if you want to save user preferences for the next time the user visit your site, is it? That is why you can tell the browser for how long you want it to save each cookie. There are two ways to

control the lifetime of the cookie:

  • expires attribute – Setting the expire attribute to a date in the future will do the trick. While this still works, this method has been suppressed by the max-age attribute
  • max-age – This attribute setup the lifetime in seconds of the cookie.

Once the expiration date has passed or the max-age lifetime has been

exceeded the browser will delete the cookie.

Cookie Path

The path defines the cookie accessibility for other pages rather than the page which created the cookie. By default, when a page creates a cookie it is accessible only for that page and any other web page in the same directory or in any subdirectories of that directory. So for example, a cookie that was created by the www.amirharel.com/cookie/cookie.html will be accessible to www.amirharel.com/cookie/other_cookie.html but not to www.amirharel.com/milk/whereismycookie.html web page.

Usually this default behavior is not what you need when developing web application with persistence mechanism. In order to control this behavior we specify the path for the cookie. This will allow any page from the same web server that contains that path to access the cookie. So for example, if we want to allow all web pages to access the cookie we just need to setup the path to: “/”.

Cookie Domain

While cookies are not accessible to web pages from a different domains, you can allow sub-domains access to the cookie by setting the domain attribute. For example, if I want to allow all my sub-domain to access a cookie I will set the domain to “/”.

Creating a Cookie

Cookies are saved using a name=value pair, where the name will be the cookie name, ands the value is the data to be stored.

Let’s see a few examples of how to create a cookie.

Let’s say I want to save the user email address in a cookie and I want to make sure the cookie will be available for a year:

document.cookie = “email=”+user.email+”; max-age=” + (60*60*24*365);

or let’s say we want to save the user preferred color scheme and we want to allow it in all our web pages:

document.cookie = “color=”+user.scheme+”;path=’/’; domain=’/’”;

Update a Cookie

Once you created a cookie you can access it with the same name, path and domain along with the new value. The lifetime can also be changed in this way.

Delete a Cookie

If you set lifetime to 0, the browser will delete the cookie.

Reading a Cookie

When reading the value from the document.cookie all the cookies accessible to this documents are returned in a name=value pairs separated by semicolons. The name is the cookie name while the value is the string that we set in the creating of the cookie. This value does not include the attributes that we set for the cookie, only the value that we assigned to it.

Cookie Limitations

While cookies are a great way to store local data, it has its own drawbacks:

  • Size limitation – cookies were designed to store small amount of data, and not for general purpose communication or data transfer mechanism. Browsers are limiting the size of the cookie to 4KB of data per cookie. While the RFC 2965 encourages browser manufactures to allow unlimited number of cookies of unrestricted size, most of the browser enforce the 4KB per cookie restriction. FireFox , Chrome and Safari are allowing more than one cookie per domain, even if each cookie is 4KB, while IE6 (didn’t tested IE7/8) will not allow more than 4KB per domain no matter how many cookies you try to save.
  • Transferring to server – all cookies are transferred to the server in the HTTP protocol. So having huge amount of data in the cookie could slow down the application performance, since all the data is being transferred to the server. Unfortunately there is no way to disable this behavior.  In order to use cookie efficiently, you can use the path and domain attributes to make sure that the cookie is only being sent to pages that needs to use it.

The Cookie Monster Object

Despite the limitations cookies have, I found them very useful for developing client side persistence. One of the most common tasks I came across is to serialize objects to be saved locally. This can be done by converting a javascript object into JSON to save into the cookie, and load a JSON from the cookie and build from it a javascript object.

The cookieMonster.js is a javascript object that performs exactly these tasks. I wrote it to myself in order to make the cookie management more easy and abstract.

How to use the Cookie Monster

The cookie monster has 3 main functions:

  • save( name, obj, expireDays, path, domain ) – this function saves an object into the browser cookie. Parameters:
    • name – the name of the cookie to be saved. This will be used in the load function.
    • obj – any javascript object. Could be a string, a number, array or a complex object with methods. (obviously methods will not be saved)
    • expireDays – number of days you want the cookie to be stored
    • path – the allowed path for the cookie
    • domain – the allowed domain for the cookie
    • Return – if the function fail it returns an error string, otherwise it returns an empty string.
  • load(name) – this function loads an object from the cookie. Parameters:
    • name – the name of the cookie to be loaded
  • remove(name) – this function delete a cookie. Parameters:
    • name – the name of the cookie to be deleted.

Cookie Monster Demo – Task Manager

I’ve created a small demo page that uses the cookieMonster.js object.

Here is the demo app:

You can also see the demo here.

In order to save and load the tasks I created an array of the tasks name: [task 1, task 2…]. I used the cookie monster object to save and load the array :


function load(firstTime)
{
    $("#taskList").empty();
    var taskData = cookieMonster.load("taskData");
    if( taskData != null )
        buildTasks(taskData);
    if( firstTime != true ) displayMsg("Data Loaded");
}

As you can see I load the task data into an object which I use to build the actual DOM objects.

The cookie monster object can also handle large data that exceed the 4KB limitation by splitting the data into several cookie in the save function, and to load them all into one object in the load function – it’s all being take care of for you so just use and enjoy.

Cookie Alternatives

There are some other alternatives for using the cookie to implement client side persistence:

  • IE userData Persistence – IE enables client side data using a DHTML behavior.
  • Flash SharedObject – Using ActionScript code you can access the SharedObject class.
  • HTML 5 Storage – Use this only if you are sure that your users are using the latest browsers.
  • Google Gears – if you want powerful stuff on the local side and you are sure that your user has installed Google Gears, maybe this could be a good solution for you. However most of the users don’t’ have Gears installed.
Bookmark and Share
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • E-mail this story to a friend!
  • FriendFeed
  • LinkedIn
  • StumbleUpon
  • Twitter

tags: , , , ,
posted in Blog by Amir Harel

Follow comments via the RSS Feed | Leave a comment | Trackback URL

  • jminkler
    What about Local storage mechanisms?
  • The jStore is a powerful jQuery extension for managing local data.
    I wrote the post to allow people to learn about the cookie mechanism, and i wanted to give something to developers who don't use jQuery and still need some cookie control.

    using jQuery just to manage cookies seems to be an overhead - at least to me. If you are using other framework like ExtJS or even using raw javascript (god forbids) this implementation can do the trick for you in a simple way.

    If someone already uses jQuery - then it makes sense to use jStore.

    Thanks for sharing.

    Amir
  • refack
    Have a look at:
    http://code.google.com/p/jquery-jstore/
    A very nice wrapper for most cookie alternatives
blog comments powered by Disqus
 
Powered by Wordpress and MySQL. Theme by openark.org