In my previous post I have been talking about IndexedDB, an in-browser database. This means, once we can persist data on the client, it’s possible to make our web application offline available. For this we have the offline application caching API.
When we want to take our application offline, the first thing we need to do is creating a manifest file. The main function of this file is describing which files have to be offline available. These files will be downloaded when the users visits the web application for the first time. Also when the manifest file has been changed since the last visit, these files will be downloaded again.
Manifest file
The beginning of the manifest file is always the same:
CACHE MANIFEST
Below this it’s recommended to place a comment with some kind of version number/date. This is necessary when you want to force the browser to download the files again because you changed one or more files. This is because browsers will only update their application cache when the manifest file is changed and not if one of the resources described in the file change. This means whenever you change a file described in the manifest file, you should update the version number in a comment.
# v3 2012-01-11
Now we have three parts in the manifest file. The first one is the explicit section. This means all files that are described in this section will be downloaded. This is also the default section, so it isn’t necessary to provide the ‘CACHE:’ title explicitly. Note that the colon after the title of the section is required. In the explicit section all kinds of files are allowed, for example: html files, images, js files, … Every resource you want to describe, takes one line.
CACHE:
/Detault.htm
/Scripts/jquery-1.7.1.min.js
/Css/ui-lightness/jquery-ui-1.8.16.custom.css
/Css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png
The next part of the manifest file will describe which files should never be cached. This is the case for pages who relay on code that is executed on the server. For example a logon page. In this section you can use the “*” character as wildcard.That’s a fancy way of saying that anything that isn’t in the appcache can still be downloaded from the original web address, as long as you have an internet connection. This also means all resources on the webpage will be cached, even if they are hosted on an other domain.
The wildcard is important if we want to provide an “open-ended” offline web application. This is common for large web applications, whom we want to make offline available such as Wikipedia.
NETWORK:
/Logon.apsx
/Secure
*
The last part of the file will describe the fallback mechanisms. If you are working offline, and you request a resources that isn’t offline available, the configured resources will be shown.
FALLBACK:
/ /HTML/Offline.htm
Offline available webpages
All webpages we want to use offline need the manifest attribute with a reference to the manifest file. This way the browser knows where he can locate the file describing the offline resources.
<html manifest="/cache.manifest">
It doesn’t matter where the manifest file is located on the server. The only thing you need is the correct path to it. There are 2 extensions that are commonly used for the manifest file. These are “.manifest” and “.appcache”. It doesn’t matter which one you use, as long as the extensions are recognized by your webserver. In IIS 7.0 or higher the a MIME-type for .manifest exists.
If u are using an Apache webserver, you can use the AddType directive in your side-wide httpd.conf by adding the following lines:
AddType text/cache-manifest .appcache "access plus 0 seconds"
AddType text/cache-manifest .manifest "access plus 0 seconds"
To avoid the risk of caching the manifest files, it is a good idea to set expires headers on your web server for manifest files so they expire immediately. In Apache you can configure this as follows:
ExpiresByType text/cache-manifest "access plus 0 seconds"
For IIS 6.0 you can find the explanation here.
Application cache events
The offline application cache API is also provided with some events:
Event | Description |
Checking | Fires when the browsers notices a manifest attribute in the html tag, even in case you already visited the page |
Downloading | Fires if the browser starts downloading the files described in the manifest file |
Progress | Fires periodically while downloading.Contains information about the number of files that have been downloaded and the number of files that are still queued |
Cached | Fires when all the files in the manifest file are downloaded. The web app is now fully cached and ready to use offline. This is only the case if it’s the first time data from the manifest file is downloaded. |
Noupdate | Fires if you visit an offline-enabled page and the manifest file hasn’t changed. |
Updateready | Fires when downloading of the files described in the manifest file was successful. The new version web app is now fully cache. This is the case if the data from the manifest file has ever been downloaded in the past. |
Error | Fires when ever something goes wrong. Possible causes: - HTTP error 404 (Page not found) - HTTP error 410 (Permanently Gone) - Page failed to download properly - Manifest file changed while updating - Browser failed to download one of the resources listed in the manifest file |
Obsolete | The manifest was not found. Possible causes: - HTTP error 404 (Page not found) - HTTP error 410 (Permanently Gone) This means the application cache has been deleted. |
It’s a best practice to call the window.applicationCache.SwapCache() method when the Updateready event is fired. This forces the browser to switch to the most recent application cache. If you forget to do this, the user needs to reload the webpage in order to take advantage of the new version.
Browser State
In the window object we have an interface “NavigatorOnline” which provides us information about the state of the browser. If the attribute “onLine” is false, we can be sure the browser is definitely offline. In case the attribute is true, the browser might be online, but that isn’t for sure.
window.navigator.onLine
There are also 2 events. The online and offline event that are fired when the browser either goes online or offline. You can attach the events on the following ways:
- using the addEventListener on the window, document or document.body
- Setting the .ononline or .onoffline properties on document or document.body to a JS function. (For some reason the window.ononline and window.onoffline will not work)
- By specifying the ononline or onoffline attributes on the <body> element in the HTML.
Note when using the first 2 solutions, you can only attach the events after the page load event.