Skip to main content
Ben Nadel at NCDevCon 2011 (Raleigh, NC) with: Vicky Ryder
Ben Nadel at NCDevCon 2011 (Raleigh, NC) with: Vicky Ryder ( @fuzie )

Pages Cached By The Cache Manifest Do Not Need To Reference The Cache Manifest

By on

In last night's post, I discovered that non-cached pages could not make use of resources cached within the application cache. As I was experimenting with that concept, I found that when I added a cache manifest reference to the non-cached page, it both became cached and was granted access to the other cached resources. This is, of course, the expected behavior and exactly what I covered in an earlier cache manifest exploration; but, the question then rose in my mind: is it the cached status or the cache manifest reference that gives one page access to other resources stored in the application cache?

After some quick testing, the answer to this question is: cached pages do have access to the entire set of cached resources regardless of whether or not the given page makes any reference to the cache manifest. In other words, it doesn't matter how a page gets cached; but once it does, it has full access to the offline application cache.

To test this, I took yesterday's experiment and simply added the main testing page (index.cfm) to the cache manifest file. Then, as before, I had the "cacher" page reference the cache manifest while the main page remained a standard HTML page:

Cache Manifest (cache_manifest.cfm)

<!---
	Define the Cache Manifest content. I'm doing it this way since
	the "CACHE MANIFEST" line needs to be the first line in the file
	and storing it in a buffer allows us to TRIM later without having
	ugly line breaks.
--->
<cfsavecontent variable="cacheManifest">

<!---
	NOTE: Cache Manifest must be the very first thing in this
	manifest file.
--->
CACHE MANIFEST

<!---
	When a cache manifest is reviewed by the browser, it uses a
	complete byte-wise comparison. As such, we can use COMMENTS
	to defunk a previously used cache manifest. In this way, we
	can use a version-comment to indicate change even when the
	file list has not changed.

	NOTE: If ANY part of this file is different from the previous
	cache manifest, ALL of the files are re-downloaded.
--->
# Cache Manifest Version: 1.8

# Cache the main page - note that the main page does not, iteself,
# have any reference to the cache manifest. It is only be cached
# by proxy of the "cacher" page.

./index.cfm

# Images that get viewed.

./images/1.jpg
./images/2.jpg
./images/3.jpg
./images/4.jpg
./images/5.jpg

</cfsavecontent>


<!--- ----------------------------------------------------- --->
<!--- ----------------------------------------------------- --->


<!---
	Let's reset the output and set the appropriate content type.
	It is critical that the manifest file be served up as a type
	"text/cache-manifest" mime-type.

	NOTE: We need to be careful about the whitespace here since
	the very first line of the file must contain the phrase,
	"CACHE MANIFEST". As such, we must TRIM() the content.
--->
<cfcontent
	type="text/cache-manifest"
	variable="#toBinary( toBase64( trim( cacheManifest ) ) )#"
	/>

As you can see, all I did here was add the "index.cfm" relative URL as a line item within the cache manifest. Then, I had the "cacher" page link to this cache manifest:

Cacher (cacher.cfm)

<!---
	Use the HTML5 doc type and provide a link to the Cache
	Manifest file for this application.
--->
<!DOCTYPE HTML>
<html manifest="./cache_manifest.cfm">
<head>
	<title>I Am The Cacher!</title>
</head>
<body>

	<h1>
		I Am The Cacher!
	</h1>

	<p>
		All I do is define a link to the cache manifest that will
		server to cache the image assets of the application.
	</p>

	<cfoutput>
		<p>
			Now: #timeFormat( now(), "hh:mm:ss TT" )#
		</p>
	</cfoutput>

</body>
</html>

Again, the only job of this page was to make a reference to the cache manifest such that the server would create the offline application cache and proceed to cache each file listed in the manifest. I needed to create this cache by proxy since I wanted to see whether or not the cache manifest reference was required in the main page (index.cfm).

Once I had my cache manifest and my "cacher" page set up, the main page was able to remain as-is:

Main Page (index.cfm)

<!DOCTYPE HTML>
<html>
<head>
	<title>Cache Manifest Test For Pages Cached By Proxy</title>
</head>
<body>

	<h1>
		Cache Manifest Test For Pages Cached By Proxy
	</h1>

	<h3>
		Pictures of Alisha Morrow
	</h3>

	<form>

		<p>
			<select id="pictureList">
				<option value="0">- -</option>
				<option value="1">Image 1</option>
				<option value="2">Image 2</option>
				<option value="3">Image 3</option>
				<option value="4">Image 4</option>
				<option value="5">Image 5</option>
			</select>
		</p>

		<p>
			<img id="viewImage" src="about:blank" width="300" />
		</p>

	</form>

	<script type="text/javascript">

		// Get the DOM references.
		var pictureList = document.getElementById( "pictureList" );
		var viewImage = document.getElementById( "viewImage" );

		// Bind the change method on the select.
		pictureList.onchange = function( event ){
			viewImage.src = ("./images/" + this.value + ".jpg");
		};

	</script>

</body>
</html>

As you can see, while this page has an HTML5 doc type, it makes no reference to the cache manifest. In fact, this page is not even cached until I execute the "cacher" page which initializes and populates the offline cache. However, once the "cacher" page is requested, and the cache is created, this main page is able to successfully access the images stored in the offline cache.

So, based on last nights post, we can see that non-cached pages cannot access resources in the offline cache; however, once a page does become cached, regardless of the means by which it became cached (through direct reference or by proxy), that cached page then has access to entire offline application cache. Again, this is something that might be pretty obvious; but when you live in the client-server world, the concept of persisted client caching raises a lot of questions!

Want to use code from this post? Check out the license.

Reader Comments

1 Comments

I've been reading through your posts on the application cache looking for a solution to recent iphone 4s problem. As I've read, pages that reference a manifest file are also cached themselves. This hasn't been my experience with pre IOS5 iphones. I was able to call a .manifest file in a .cfm file, with the manifest loading jquery, .js, and .css files but still calling the parent .cfm each time so session variables could be accessed. Now, after the switch to ios5, all the iphone 4s' ignore the .cfm (used the cached version) as some have said.

Seems like I am at a crossroads - use the application cache to speed up the web app or ditch it to retain some server side processing. Luckily, the session variables referenced in the CFM are notifications and debugging info so the app. continues to run but this will spur my move to Appcelerator.com or Corona so there are fewer hoops to jump through.

Thanks for your work Ben. You and Ray are always the go to guys for info.

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel