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

Posted June 23, 2010 at 9:35 AM by Ben Nadel

Tags: ColdFusion, Javascript / DHTML, HTML / CSS

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!




Reader Comments

Oct 31, 2011 at 5:38 PM // reply »
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.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Jun 18, 2013 at 9:20 PM
Mapping AngularJS Routes Onto URL Parameters And Client-Side Events
I couldn't find examples of passing multiple arguments using the when() routing statement so figured out through trial and error that you can pass multiple arguments using the following format: .whe ... read »
Jun 18, 2013 at 3:39 PM
Experimenting With The Amazon Simple Storage Service (S3) API Using ColdFusion
Hi Ben, THANKS! While not bleeding edge, it is new to me & I like learning new things every day! ... read »
Jun 18, 2013 at 12:30 PM
Disabling Auto-Correct And Auto-Capitalize Features On iPhone Inputs
Also spellcheck="false" should be mentioned as part of html5 specs ... read »
Jun 18, 2013 at 8:40 AM
Using Named Functions Within Self-Executing Function Blocks In Javascript
Hi Ben, you forgot to mention the most important thing for named self-executing functions - they can be referenced by name ONLY inside their execution context (which is parens in this case), it mean ... read »
dee
Jun 18, 2013 at 7:01 AM
My Safari Browser SQLite Database Hello World Example
hai ben, this program is really good i could understand the concept but i dint know how to save it and how to open it as you have done in the video can u give that details pls ... read »
Jun 18, 2013 at 6:04 AM
Clearing Inline CSS Properties With jQuery
Thanks a lot for for post! It helped me a lot... after being stuck since 24 hrs.. found solution from your post. Thanks again! ... read »
Jun 18, 2013 at 2:31 AM
SOTR 2013 - The Best Conference I Never Went To
I keep watching it, should keep me happily distracted until SotR14 ;) ... read »
Jun 17, 2013 at 9:45 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, As I was reading what you wrote, it occurred to me that maybe I do something similar to that in some of my client-side code. In an application I'm working on, there are a bunch of unrelated ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools