Module 09 - Adding Offline Support To Web Applications
Module 09 - Adding Offline Support To Web Applications
Contents:
Module Overview
Module Overview
Web applications have a dependency on being able to connect to a network to fetch web pages and data. However, in some
environments a network connection may be intermittent. In these situations, it might be useful to enable the application to
continue functioning by using data cached on the user's device. HTML5 provides a choice of new client-side storage options,
including session storage and local storage, and a resource caching mechanism called the Application Cache.
In this module, you will learn how to use these technologies to create robust web applications that can continue running even
when a network connection is unavailable.
Objectives
• Save data locally on the user's device, and access this data from a web application.
• Configure a web application to support offline operations by using the Application Cache.
One key strategy that a web application can use to cache data is to store it locally in the file system of the user’s device. This is
not a new strategy, and it has formed the basis of several mechanisms used by web servers to simulate user sessions. This lesson
describes some of the technologies that are currently available.
Lesson Objectives
After completing this lesson, you will be able to:
• Explain how a web application can use cookies to maintain simple state information.
• Use the Session Storage API to save session state information in a web application.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&F… 1/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
• Describe how the Indexed Database API can implement a structured data store on the user's device.
At their best, web applications are stateless, meaning that a web server has no notion of a continuous client session. When a user
connects to a website, the web server simply serves the page requested by the user's browser. If the user views another page, the
web server retrieves that page and sends it to the user's browser. As far as the web server is concerned, the two requests are
completely independent. This mechanism can pose a problem if the second page requires data that the user entered on the first.
To facilitate the seamless connection among web pages, the browser needs a mechanism to store information representing the
state of the client's session. The browser can transmit this data as part of any request to view a page in the website so that the
server can associate the page request with data previously entered by the user. This is the basic premise behind the cookie
protocol.
A cookie is nothing more than a text file with a small number of fields that can be used to identify the user's session and cache
information about the user. Cookies can persist data between browser sessions in order to provide a seamless experience when a
user revisits a web site. A good example of this continuity is the Amazon® website, where even if you have not logged in,
Amazon can recognize you, and personalizes your pages according to its analysis of your interests and preferences. This
personalization is achieved by using cookies; information about a user's preferences is stored locally on the user's computer, and
this information is transmitted as part of each request sent to the Amazon website.
Cookies can only store a very small amount of data, up to 4 KB. There is an important reason for this limitation. Cookies are
designed to be sent to and from the web server on each and every page request. If they were any bigger, their bandwidth
requirements could have a significant impact on the responsiveness of the web application. However, just as the web has
evolved, so has the use of cookies. Increasingly, they are used to store far more than just session tokens. Cookies have become a
place to store important user profile data, page history, and other data.
The grave danger in keeping user data in cookies is that information can be shared unintentionally (or otherwise) between
websites, and in recent times they have become notorious for betraying users’ personal information without their consent.
Throughout the European Union, recent legislation forces websites hosted in these countries to notify a user if they use cookies,
and to enable the user to disable them.
Another issue to be aware of is that users often open several tabs when browsing a single site. The data held in cookies is shared
between these tabs, but cookies have no defined synchronization or concurrency mechanism. This can lead to undesirable
effects if the values held in a cookie are changed in one tab, and are then used in the second tab mid-process.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&F… 2/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
Since cookies are designed to associate a user session with a web application, they are mapped to URLs either at the root level or
a subdirectory level, and to individual pages, betraying their allegiance to a time when web servers were essentially just file
servers, and applications were essentially just HTML pages in folders. This is no longer an accurate paradigm. For example, the
model-view-controller (MVC) pattern implemented by many common web applications disassociates the physical server file
structure from the URLs used to fetch pages and other resources.
In an increasingly semantic web, cookies are becoming less useful, and clearly raise some significant concerns if misused.
Cookies were never designed to be used as a wholesale storage technology, and HTML5 introduces new client-side storage
paradigms to overcome many of shortcomings of cookies. These technologies include the Session Storage API and the Local
Storage API.
Session storage is a browser-persistence mechanism that can store text data on the device running the browser. As the name
implies, data kept in this store lasts for the duration of the current user session. When the user closes the browser, the session
store is cleared automatically.
Session storage is widely supported and has been implemented by the major browsers, including Internet Explorer, since 2009.
You access session storage by using the sessionStorage property of the window object. You can test whether a browser
implements session storage by querying for the presence of this property, like this:
if( window.sessionStorage ){
...
}
Session storage associates each item of session data with a unique key value; you provide this key value when you store a value,
and use this same key value to retrieve the data. The Session Storage API provides three ways to store and retrieve data:
• setItem and getItem functions. The setItem function expects you to provide the key and the data to store. The getItem
function uses the key to return the data. If there is no data with the specified key, the value returned is null.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&F… 3/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
• name-key pair. You can use array notation, and specify the key value as the array index.
• pseudo-properties. You can add a property for each key to the sessionStorage object.
Note: You do not have to prefix these calls with the window object. You can call them directly because window is
the default calling context.
If you need to persist objects in session storage, serialize them as JSON strings by using the JSON.stringify() function.
Objects in the session store are also accessible as an array of items with a long index. You can test the length property to find out
how many keys are in the sessionStorage object. You can retrieve the key for each object by using the key() function. This
information can be very useful for iterating over items, as shown in the next code example, which creates a list of the keys in the
sessionStorage object and displays them in a <div> element :
sessionStorage.removeItem("myKey");
To clear a session store before the end of the session, call the clear() method:
sessionStorage.clear();
Remember that if you don't clear the data for a session, it will be cleared automatically when the user closes the browser window.
Consequently, session storage may be of limited use for applications where you need to preserve user data between sessions.
This is where the Local Storage API may prove more useful.
Additional Reading: For more information about the session storage API, visit http://go.microsoft.com/fwlink/?
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&F… 4/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
LinkID=267733.
Local Storage also enables you to store data items on the client browser, but unlike session storage, items in local storage are
persisted even after the browser session has ended. The data is stored in the file system of the device running the browser. It is
removed when the web application deletes it, or when the user requests that the browser remove it. This mechanism is browser
dependent.
Data persisted in local storage is available across different web pages, although it is only available to web pages running as part of
the website that stored the data; you cannot use local storage to share data between pages originating from different websites.
You access local storage by using the localStorage property of the window object. You can detect whether the browser supports
local storage by querying for the presence of this property, as follows:
if( window.localStorage ){
...
}
The Local Storage API is very similar to the Session Storage API. You can store and retrieve data by using the setItem() and
getItem() functions, a name-pair key, or pseudo-properties.
You can determine the number of items in local storage by using the length property, and iterate over items and retrieve data by
using the key() function, as shown in the following example:
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&F… 5/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
localStorage.removeItem("myKey");
To remove all items from the store, call the clear() function:
localStorage.clear();
Objects stored in local storage do not have a specified size restriction. Instead, the store is free to grow to an upper size limit
decided by the user and configured in the browser settings. This makes it ideal to store large amounts of data useful to the client-
side application. As with the session storage API, you should serialize objects as text by using the JSON.stringify() function before
storing them.
Using local storage instead of relying on server round trips has a significant impact on the user experience. Data found on the
client can be displayed almost instantly, improving the responsiveness of the website.
Additional Reading: For more information about the local storage API, visit http://go.microsoft.com/fwlink/?
LinkID=267734.
The storage API to which both session and local storage conform includes a single event called storage. You can use this event
to notify a web page of changes to data held in the store; it fires whenever data is modified.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&F… 6/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
function myStorageCallback( e ) {
alert("Key:" + e.key + " changed to "
+ e.newValue);
}
window.addEventListener("storage",
myStorageCallback, true);
The event object passed to the event handler includes the following properties:
The event model enables web pages to listen for storage events and to update themselves when data they use from the store
changes state. For example, in Internet Explorer, if you have the same web page open in multiple tabs, the data on each tab tabs
can remain synchronized in order to reduce the scope for inconsistencies caused by changes made in different tabs.
Internet Explorer also defines the storagecommit event. The storage event fires when data changes, but the storagecommit
event occurs when data held in local storage is actually written to disk.
function myStorageCommitCallback( e ) {
alert("Data written to disk");
}
window.addEventListener("storagecommit", myStorageCommitCallback, true);
Reader Aid: For more information about handling storage events, visit http://go.microsoft.com/fwlink/?
LinkID=267735.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&F… 7/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
The Indexed Database API, or IndexedDB, provides an efficient mechanism for storing, retrieving, and searching for structured
data held locally on the device running the browser. You access IndexedDB by using the indexedDB property of the window
object.
You store data in a named database; you connect to a database by creating a request object that references the open() function.
If the database does not exist, the open() function creates it. The IndexedDB API is asynchronous, and you use the onsuccess
event to capture the value returned by functions such as open(). If a function fails, you can determine the reason for the failure
by handling the onerror event. The following example shows how to open a database and obtain a reference that you can use for
storing and retrieving data. The db variable holds a reference to the database, if it is opened successfully:
Note: Request objects execute when they go out of scope; that is, when the current JavaScript block finishes. For this
reason, in the example code above, it is perfectly safe to assign the onsuccess and onerror callbacks after setting the
openRequest variable because the open() function will not run (and invoke the callbacks) until control reaches the
end of the JavaScript block.
A database holds one or more object stores, which are analogous to tables in a relational database. You define an object store by
using the createObjectStore() function; you specify an object to add to the store together with the name of the key property
that the IndexedDB API can use to retrieve the object. The following example creates an object store for holding the details of
conference attendees. The object store is initialized with the details of the first attendee—Rachel Valdez. The id property is the key
to the object store:
var attendee = {
id: "1",
name: "Rachel Valdez",
password: "Pa$$w0rd"
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&F… 8/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
};
var attendeeStore = db.createObjectStore("attendees", { keyPath: "id" });
Additional Reading: You should only create a new object store in the context of a VERSION_CHANGE transaction. At
the time of writing, the IndexedDB API specification is currently fluid in this area. Some vendors initialize a
VERSION_CHANGE transaction by using the setVersion() function of a database, while other vendors start a
VERSION_CHANGE transaction implicitly if you specify the version number as a second parameter for the open()
function of the indexedDB object; this is the approach that Internet Explorer 10 takes: // Create version 2 of the
database and start a version change transaction var openRequest = indexedDB.open("contosoDB", 2); Internet Explorer
triggers the upgradeneeded event, which runs in the context of the version change transaction. You can use this event
to add the object store to the database:
openRequest.onupgradeneeded = function(event) {
var db = event.target.result;
var attendee = {
id: "1",
name: "Rachel Valdez",
password: "Pa$$w0rd"
};
var attendeeStore = db.createObjectStore("attendees", { keyPath: "id" });
}
For more information about opening a database and initiating a version change transaction, see the latest version of
the IndexedDB specification at http://go.microsoft.com/fwlink/?LinkID=267736.
You can use the add() function to store additional records in an object store. The next example adds the details for Eric Gruber to
the store. Notice that the add() function is asynchronous:
var newAttendee = {
id: "2",
name: "Eric Gruber",
password: "Pa$$w0rd"
};
var addRequest = attendeeStore.add(newAttendee);
addRequest.onsuccess = function(event) {
// Attendee was successfully added
}
addRequest.onerror = function(event) {
// Handle failure
};
If a record with the same key value as the new item already exists, the add() function fails and raises the error event.
var updatedAttendee = {
id: "2", // Id of existing attendee
name: "Eric Gruber",
password: "P@ssw0rd"// Change the password
};
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&F… 9/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
You can use the delete() function to remove an object from the object store. Specify the key of the object as the parameter. If
there is no matching object, the error event is raised:
}
deleteRequest.onerror = function(event) {
// Handle failure
};
To find data in the object store, you can use the get() function and specify the key of the object to retrieve. Again, if there is no
matching object, the error event occurs:
var attendee;
var getRequest = attendeeStore.get("2"); // Retrieve the details for Eric Gruber
getRequest.onsuccess = function(event) {
// Attendee details are available in event.target.result
attendee = event.target.result;
}
getRequest.onerror = function() {
// Handle failure
};
The IndexedDB API defines many more features. For example, you can create transactions if you need to batch operations
together, you can use a cursor to fetch multiple records from an object store, and you can define indexes to speed up queries that
retrieve objects by using specified properties.
Note: To use the IndexedDB API, Internet Explorer, must be configured to allow website caches and databases. This
option is available on the Settings page of the Internet Options dialog in Internet Explorer; click the Caches and
databases tab, and then select Allow website caches and databases.
Additional Reading: For more information about using the IndexedDB API, visit http://go.microsoft.com/fwlink/?
LinkID=267737.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 10/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
The session storage, local storage, and IndexedDB APIs provide a programmer-centric model for storing and managing data
locally on a user's device. In addition, HTML5 features a mechanism for caching web pages and other resources so that once they
are downloaded to the client machine, the browser defers to this cache and not the network. After the page is downloaded, there
is no need to retrieve it again. This saves on network resources, and enables developers to build web applications that do not
even need web connectivity once they are client-side. The fact that a web page or other resource is cached is transparent to the
JavaScript code running on a web page, although the Application Cache API includes functions and objects that enable
JavaScript code to detect whether a page is running online or offline, and to refresh the cached resources if a network connection
is available.
In this lesson, you will learn how to configure and use the HTML5 application cache in a website.
Lesson Objectives
After completing this lesson, you will be able to:
Large parts of web applications are simply file-based resources such as HTML pages, CSS files, JavaScript files, and images. There
is little point in downloading such static files over and over, and yet this is what a typical browser session does.
The application cache is a client-side storage mechanism that enables the developer to explicitly declare which static files should
be cached by the browser. You can use this mechanism to create websites that run just as well offline as they do online, making it
ideal for developing robust mobile applications that have to run with intermittent network connections.
The cache manifest file specifies the data that the web browser should retain in the application cache. This file is a list of
resources divided into separate sections labeled CACHE, NETWORK, and FALLBACK. The information in these sections
determines how the browser responds when a request is made for a resource when the web application is running in the online or
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 11/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
offline states.
To add a manifest file to an application, create a new text file and store it in the root folder of the web application. In this file, list
all the static resources that should be downloaded and cached. This list will most likely include any graphics and images in the
application, any HTML pages that do not have URL data dependencies, CSS files and JavaScript files, and so on. An example
manifest file looks like this:
CACHE MANIFEST
CACHE:
index.html
verification.js
site.css
graphics/logo.jpg
NETWORK:
login
# alternatives paths
FALLBACK:
ajax/account/ noCode.htm
Note: The .manifest extension file is of a new MIME type called text/cache-manifest. You may need to configure the
web server to serve this type of file by adding this new MIME type, if it is not already set up.
The cache manifest file starts with the line CACHE MANIFEST; if this line is missing, the file may not be recognized as a manifest
file. The file can contain the following sections:
• CACHE: Resources listed in this section are downloaded once, when the web page is initially loaded into the user's browser.
Thereafter, the cached version of these resources will be used and they will not be updated from the server.
• NETWORK: Resources listed in this section will always be downloaded if the network is available. They are not cached.
• FALLBACK: Resources listed in this section are not cached, but you provide an alternative URL for them should the server
become unavailable. In the example shown, all URLs prefixed with the ajax/account/ path will be replaced with the
noCode.htm file if they cannot be retrieved. The alternative resources, such as the noCode.htm file in the example, are cached.
Note: Be sure to add the colon after the CACHE, NETWORK, and FALLBACK keywords, otherwise they might not be
recognized. If you do not specify any sections, then CACHE is assumed.
You can add comments to the manifest file by creating a new line starting with the pound symbol, #.
To use the application cache, each web page must reference the manifest file that lists the resources to cache. A website can
contain multiple manifest files, and different web pages can reference different manifest files. You specify the name of the
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 12/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
manifest file to use in a web page by adding the manifest attribute to the <html> element.
<html manifest="appcache.manifest">
Note: As with the IndexedDB API, to use an application cache, Internet Explorer must be configured to allow website
caches and databases. This option is available on the Settings page of the Internet Options dialog in Internet Explorer;
click the Caches and databases tab, and then select Allow website caches and databases.
The contents of the application cache are managed by the browser by using the configuration specified in the cache manifest
file. However you can monitor the application cache from JavaScript code by using the Application Cache API.
The application cache is accessible to JavaScript code through the applicationCache property of the window object. The
application cache object returned by this property introduces a comprehensive event model covering the lifecycle and behavior
of the cache. These events include the following:
• checking: This event fires when the browser examines the application cache for updates.
• downloading: This event fires when the browser starts downloading resources to the application cache.
• updateready: This event fires when the new version of the cached objects for a web page have been downloaded.
• obsolete: This event fires if the manifest file is no longer available and the application cache is no longer valid for the current
web page.
• cached: This event fires when the application cache is ready and available for use.
• error: This event fires if an error occurs while downloading resources to cache, or when checking for resources to download.
• noupdate: This event fires if no changes were found after checking the manifest for updates.
• progress: This event fires as each resource specified in the manifest is downloaded to the application cache.
The following example shows how to catch the error event of the application cache:
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 13/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
Note: Just as with the local storage and session storage objects, you do not have to reference the applicationCache
property from the window object, because that is the default context.
The application cache also implements a numeric status property that can be tested independently of the event model. This
property can have one of the following values:
0 UNCACHED The page is not associated with a cache. No resources have been downloaded
1 IDLE All cached resources have been downloaded. The cached event has been fired.
2 CHECKING The cache is being checked for updates to download. The checking event has been fired. If no
updates are found, the noupdate event is fired.
3 DOWNLOADING Resources are being downloaded to the cache. The downloading event has been fired.
4 UPDATEREADY The cache has been updated with new resources, and all resources have been downloaded. The
updateready event has been fired.
5 OBSOLETE The manifest is missing and no cache is available. The obsolete event has been fired.
Additional Reading: For more information about using the Application Cache API to monitor the application cache,
visit http://go.microsoft.com/fwlink/?LinkID=267738.
The behavior of the cache depends entirely on updates to the manifest file. Making a change to a resource on the server no
longer guarantees the browser will get the latest version of the file; if a web page caches a resource, the resource will be loaded
from the application cache even if there is a newer version on the server.
To force an update to get the new version of an existing resource, you must make a significant change to the manifest file.
Simply updating the last modified date is not enough to trigger a complete refresh on the browser. The best way to force an
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 14/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
update is to add a comments field in the manifest with a version number, for example:
#version=1.2.3
A change to this comment will be acknowledged as a change to the manifest file, for example:
#version=1.2.4
You can also use the update() function of the applicationCache object to initiate a check for updates, similar to the one
performed when a web page is first loaded. Any existing cached resources will continue to be used until the page is reloaded or
you invoke the swapCache() function of the applicationCache object.
In the code example below, the swapCache() function is called if the cache has been updated with new resources (status code 4 is
the UPDATEREADY status). This code forces the web page to use the new resources.
applicationCache.update();
...
if (applicationCache.status == 4 ) {
applicationCache.swapCache();
}
Sometimes it makes sense to temporarily hide or disable functionality in a web application if no network connection is available.
For example, if a web page expects a user to enter and submit data to a server by using a form, then this feature will not work
unless an active link to the server is available. In situations such as this it does not make sense to cache the web page.
You can detect the network connectivity in an application by using the onLine property of the navigator object. This is a Boolean
property that is true if a network connection is available, false otherwise. The navigator object also provides two events called
online and offline. These events fire when the network state changes.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 15/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
The following code example shows how to detect the network status of a page when it loads. The onload event handler examines
the onLine property of the navigator object and displays the status in the statusDiv div on the page. The online and offline
event handlers fire and update the displayed status if the network connectivity changes.
var s;
function onlineStatus() {
s.innerHTML = "Online.";
}
function offlineStatus() {
s.innerHTML = "Offline.";
}
onload = function() {
s = document.getElementById("statusDiv");
if( navigator.onLine ) {
onlineStatus();
} else {
offlineStatus();
}
window.addEventListener("online", onlineStatus, true);
window.addEventListener("offline", offlineStatus, true);
}
Scenario
The conference organizers are concerned that the venue has poor Wi-Fi coverage in some locations, meaning that attendees
might not always be able to access the conference website on their tablets and laptops. The Schedule page is especially
important because attendees need to know when sessions are running.
You have decided to make parts of the web application available offline by using the offline web application features of HTML5.
After an attendee has visited the online website once, their browser will have downloaded and cached the important pages. If a
Wi-Fi connection is unavailable, the attendee will still be able to view the website by using the cached information.
Objectives
After completing this lab, you will be able to:
1. Use the Application Cache API to make web pages available offline.
2. Use the Local Storage API to persist user data locally between browser sessions.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 16/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
• Password: Pa$$w0rd
Scenario
In this exercise, you will make the Home, About, Schedule, and Location pages available offline.
First, you will complete the creation of an application manifest file, which lists all of the files that should be cached for offline
access. Next, you will reference the manifest file from the Home, About, Schedule, and Location pages. Then, you will write
JavaScript code that adapts the page navigation, hiding links to pages that are not available offline. Finally, you will run the
application and view the Schedule page. You will stop the web server and then reload the Schedule page to verify that it works
offline.
2. Start the 20480B-SEA-DEV11 virtual machine if it is not already running, and log on as Student with the password
Pa$$w0rd.
o In the Website Data Settings dialog box, click the Caches and databases tab.
o Select the Allow website caches and databases check box, and then click OK.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 17/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
4. Start Visual Studio and open the ContosoConf.sln solution from the E:\Mod09\Labfiles\Starter\Exercise 1 folder.
5. Open the appcache.manifest file. This file contains a partial application manifest that lists the resources a web browser must
cache for offline access.
6. After the comment near the start of the file, insert the following URLs to cache the Home, About, Schedule, and Location
pages:
/index.htm
/about.htm
/location.htm
/schedule.htm
7. Add the manifest="/appcache.manifest" attribute to the <html> element of the Home, About, Schedule, and Location
pages. These are the pages that will operate offline by using the application cache.
1. Open offline.js file in the scripts folder. This script contains methods that hide or show links depending on whether a page
is currently running in online or offline mode. The pages that support offline mode reference this script.
2. After the comment // TODO: if currently offline, hide navigation links that require online, add JavaScript code to detect if the
web browser is currently offline, and call the hideLinksThatRequireOnline() function.
o Examine the navigator.onLine property to determine whether the browser is online of offline.
3. After the comment that starts with // TODO: add onoffline and ononline events to document.body, handle the ononline
and onoffline events for the document body; call the hideLinksThatRequireOnline and showLinks functions as
appropriate.
4. After the comment // TODO: also handle the applicationCache error event to hide links, add an event listener to the
applicationCache error event, which calls the hideLinksThatRequireOnline function.
2. Expand the Windows notification area, right click IIS Express, and then click Exit. Allow IIS Express to exit when prompted.
Note: When IIS Express first starts running, the IIS Express icon may appear in the Windows task bar rather than the
notification area. If this occurs, right-click the IIS Express icon and then click Exit.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 18/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
3. In Internet Explorer, view the Schedule page. Verify that the page loads and displays the schedule information. Also verify
that, after a brief delay, the Register link in the navigation bar is removed. This occurs because the Register page is not
cached (it is not included in the appcache.manifest file), and registration requires an active connection to the web site.
4. View the About page and verify that this page displays correctly, and that the Register link disappears from the navigation
bar.
Results: After completing this exercise, you will have modified the web application and made the Home, About, Schedule,
and Location pages available offline.
Scenario
Currently, the Schedule page is able to display sessions when offline, but this information does not include whether the attendee
selected the session by using the star icon. This information is stored on a remote server that is inaccessible when the application
is running offline. However, attendees also need to see the sessions they have selected. This information should be saved locally
on an attendee’s computer, so it is available offline.
In this exercise, you will update the JavaScript code for the Schedule page to record an attendee's selected sessions. You will
create an object that wraps the Local Storage API. Then you will use this wrapper to save information locally about starred
sessions. Finally, you will run the application, view the Schedule page, and verify that the starred sessions are persisted even when
the web server is not available.
Note: The Local Storage API is very simple. It can only save and load string key-value pairs. Persisting more complex
data requires serialization. In this exercise, you will use a wrapper around the Local Storage API.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 19/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
4. Use the local storage wrapper to save and load data in the Schedule page.
3. Close IIS Express by using the icon in the Windows notification area.
4. On the Schedule page, click some of the stars, and then refresh the page.
5. Notice that information about which sessions are starred is not saved when the application is running offline (the yellow
stars turn white again).
1. In the scripts folder, open the LocalStarStorage.js file. The code in this file wraps the Local Storage API to provide a higher-
level interface used by the application code.
Note: The Schedule page will use the addStar, removeStar, isStarred, and initialize functions defined in this file.
These functions in turn call the save and load methods that you will implement in this task.
• The IDs of the starred sessions to be saved are held in the array this.sessions.
• Convert the array to a string by using the JSON.stringify function, and save this string to local storage with the key stars.
• Handle the cases when the local storage returns no data or invalid JSON. In these situations, set this.sessions to be an empty
array.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 20/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
Task 4: Use the local storage wrapper to save and load data in the Schedule page
• Detect whether the session identified by this.id is starred (use the isStarred method of the localStarStorage object).
• If the session is starred, tag the element with the starred CSS class so that it is rendered correctly (use the statement
this.element.classList.add(this.starredClass);).
5. After this comment, add JavaScript code to remove the star from the session identified by this.id. Use the removeStar
method of the localStarStorage object.
7. After this comment, add JavaScript code to add a star to the session identified by this.id. Use the addStar method of the
localStarStorage object.
1. Open the appcache.manifest file and insert a version comment near the top of the file. As follows:
CACHE MANIFEST
# version 2
...
Note: The JavaScript files are listed in appcache.manifest, and they will have been cached by the web browser. Making
a change to the appcache.manifest file forces the browser to download the updated scripts.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 21/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
3. In Internet Explorer, refresh the page to ensure the updated scripts are used.
4. Close IIS Express by using the icon in the Windows notification area.
5. On the Schedule page, click some of the stars, and then refresh the page.
o In the Website Data Settings dialog box, click the Caches and databases tab.
o Clear the Allow website caches and databases check box, and then click OK.
Results: After completing this exercise, you will have updated the Schedule page to locally record starred sessions.
In this module, you have seen several techniques that you can use to store data locally on the device that is running the browser.
These techniques include session storage for storing session data that is automatically removed when the user's browsing session
completes; local storage, which provides for more persistent data on the user's device; and the Indexed Database API, which
enables the browser to store and retrieve data in a more structured manner.
You have also learned how to use the application cache of HTML5 to configure web pages and to enable them to cache
resources locally on the user's device.
Review Question(s)
Question: What are the primary differences between data retained on a user's device by using session storage and by
using local storage?
Verify the correctness of the statement by placing a mark in the column to the right.
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 22/23
9/5/2014 Module 9: Adding Offline Support to Web Applications
Statement Answer
You configure a web page to use the application cache to cache a resource locally. If the resource is modified at the web server,
then the browser automatically downloads the latest version. True or false?
https://skillpipe.courseware-marketplace.com/reader/en-GB/Book/BookPrintView/c58ca3cf-8b33-4812-87d6-b4593bb364f0?ChapterNumber=11&FontSize=1&… 23/23