Offline web applications with HTML5
eb applications are preferred over desktop applications because they are available 24x7 and are accessible from anywhere in the network. A couple of years back, the term network implied wired-network but more recently, due to availability of high-speed wireless networks and handy mobile devices, the dependency over wired-network has diminished greatly. Via wireless connectivity, web applications are now accessible from literally anywhere. But there could be situations when internet connectivity may get lost. This loss of connectivity could be due to various reasons, like user is in transit or is switching between networks or is simply at a remote location where the wired/wireless network isn't available.
Major drawback of a typical web application is that, the moment internet connectivity is lost; it can no longer be accessed or used. Most of the desktop applications do fairly well in this situation. They switch to disconnected or offline mode and ensure continuous user experience even during loss of network connectivity. Offline mode requires availability of local cache. Applications keep a copy of the online data and the data entered during the offline mode in application cache. Example of a desktop application supporting disconnected mode is e-mail client application. It caches e-mail folders and calendar appointments locally and allows browsing them in offline mode.
Designing web application to support offline mode has been a challenge so far. Various architectural solutions exists which either requires setting trust relationship in browser or involves smart client installation. HTML5 recognized this architectural pain-point and elegantly provisioned for offline capability. Let's see how.
Developing an offline web application has twofold issues. One, how to make web application/pages available in disconnected mode and two, how to cache large data?
Making pages available offline
All browsers have some sort of caching mechanism. Most of the browsers offer "work offline" feature on top of this mechanism. Leveraging browser's "work offline" feature might appear as an easy way for developing an offline web application but it has the following limitations.
1. In offline mode, only previously visited pages can be viewed
2. To be able to view pages from cache, user has to manually put the browser in offline mode and once internet connection is available, he has to toggle it back to on-line mode
3. A web page can have multiple links and web application developer has no control over which parts of the page (like the external script files, image resources etc) or depth of links that the browser caches when user visits the online web application
4. Browser dumps all web pages that user visits at a common location. Moreover, while cleaning browser's temporary storage, there isn't any way to retain cached pages pertaining to a specific web site or web application. Hence, there are good chances of losing the offline page viewing capability after running cleanup application.
HTML5 attempts to resolved such issues with application caching API, which is the mechanism to ensure web application's availability in disconnected mode. Application caching API begins with manifest attribute on html element. This attribute takes URI of the manifest file. Manifest file is a simple text file listing the web page resources, like image or external scripts, which the browser should or should never cache. The manifest file can have any name but it has to be identified as text/cache-manifest MIME type resource on web server.
Figure 1 manifest.cache
In figure 1, shows manifest file details. As suggested by MIME type (set on web server), the manifest is a text file. The file is divided in following 3 logical sections
1. Cache - This section lists the resources which should be cached after loading them.
2. Network - This section contains the white-listed resources. That is the resources browser should never cache. Browser always bypasses cache and contacts server while loading resources listed in this section
3. Fallback - This section details the backup strategy. If browser fails retrieving original content (koala.jpg in this case) then browser should use fallback resource (Jellyfish.jpg in this case)
After creating the manifest file, add its reference in the html element on the web page as shown in figure 2.
Figure 2 offline.html
Caching user data
The second important requirement for an offline web application is client side caching. Typically cookies are used for client side data caching. But from an offline web application's perspective, cookies are not useful because
1. Most browsers restrict cookie size to 4 KB and don't allow more than 20 cookies per domain. This makes a maximum of 80KB storage space available as client side cache. Which could be OK from session tracking perspective but is too scanty for an offline application (Note: cookies are primarily for HTTP state management).
2. Cookies don't support transaction boundaries and tend to "leak" information across browser windows. For example, while booking ticket from a single site, if 2 browser windows are used to navigate ticket/route information, there is very good chance that the user unintentionally ends up buying 2 tickets, if the ticket booking site relies on cookies to keep track of the ticket being bought.
To address above issues, HTML5 has introduced localStorage and sessionStorage objects. The sessionStorage fixed the "leak" issue described in point 2, whereas localStorage is the really targeted at offline web applications. Both the storage objects don't have storage size restrictions and they unleash megabytes of (and more based on user setting) client-side caching space. For developers, the local and session storage objects are available as attributes of the Windows object which is part of browser's DOM hierarchy. Both the storage objects store data in as key/value pair.
Storing and retrieving data from localStorage object is shown in GetUserID and SetUserID functions in figure 3.
Figure 3 Activation.js
Making it work
With this basic information, let's try to prepare a web application for offline mode. To begin with, create manifest.cache, offline.html and activation.js as per figure 1, 2 & 3. Then create folder structure as seen in figure 4. Note that the stylesheet.css is optional. Remove stylesheet.css entry from the manifest file if you don't want to apply common style to multiple pages. Now, map OfflinePage folder (ref: figure4) as virtual directory in IIS (any other web-server can also be used for publishing is web application). Then access Offline.html page as http://localhost/OffLinePage/Offline.html.
Figure 4 Folder structure
While loading Offline.html page, browser may seek user permission to cache page content. Allow browser to cache. Then stop IIS, close the browser and try accessing http://localhost/OffLinePage/Offline.html. The browser would not only load Offline.html but it would also show SecondPage.htm after clicking the "Visit this link" hyperlink. Note that browser cached SecondPage.html page even though it was never visited while IIS was ON and serving pages. Using button, any text string can be stored in browser's local storage and the stored string can be retrieved using button
· <!DOCYPE html> declaration is a mechanism to distinguish HTML5 html page
· Before trying to access Offlline.htm from browser, ensure .cache files are mapped to text/cache-manifest MIME type in IIS
· Above code worked well with FireFox 3.6.10, Safari , 5.0(7533.16), Opera 11.00, Chrome 9.0.597.98 but did not work on IE 8.0.7600.16385
· The same HTML files would work on mobile platforms
· Setting MIME type for the manifest file on web server, definition of stylesheet.css & contents of SecondPage.htm are not included in this post for brevity