SHARE
Facebook X Pinterest WhatsApp

Programmatically Trigger an Application Cache Download

Written By
thumbnail Rob Gravelle
Rob Gravelle
Jan 20, 2014

Although there are a lot of good things that can be said about the new Application Cache (AppCache) specification, there is still room for improvement. One criticism that comes up a lot is its implementation is too inflexible. The crux of the issue lies in the way that the manifest file is declared as an attribute of the HTML tag. That makes it difficult to control the downloading of the manifest file so that you can give visitors a heads up as to what’s about to happen. As it stands, a warning dialog is the only tip-off that resources are being downloaded. Having said that, there is a way to kick off an AppCache download via a script. Read on to learn all about it!

The IFrame & JavaScript Solution

The most satisfactory dynamic AppCache download implementation that I have tried is to load a second page within an iframe. As an extra precaution, the content of the iFrame is not loaded until the download event is triggered via a user action. The serving of cross-site content in iframes has given them a bit of a bad name, but what we’re doing here is a perfectly legitimate use of an iframe because we are loading content from the same server. Even the most restrictive browser will allow same-site content in an iframe:

The HTML Markup

Just about any user action or event can be utilized to kick off the loading of the iframe document, but the simplest is of course a button. A couple of other elements worth noting in the code snippet below are the results, which is a DIV that presents messages to the user, replacing annoying alert boxes. Normally, the element styling would be defined in the CSS file, but I included it here for the sake of simplicity. The content-area DIV will hold other page contents unrelated to the AppCache. However, I included it here because it is referenced by the code that appends the iframe to the document:

<input type="button" id="downloadAppCache" class="mobile_button" value="Download App Cache" />
<div id="results" style="color: white; font-size: 1.2rem; margin: 10px; height: 100px;"></div>
<div id="content-area"></div>

The Button Click Event Handler

In the JavaScript file, the button handler is bound to the click event using the unobtrusive jQuery click() function. In the anonymous handler function, a reference to the iframe object is obtained using the get() with an index of zero. That unwraps the iframe element from the jQuery holder object so that we can call its native update() function on subsequent button clicks. An if statement checks whether or not the iframe exists and either updates it or creates it if it does not:

$(document).ready(function() { 
  $('#downloadAppCache').click(function() {
    var appCacheFrame = $('#offlineAppDownloadFrame').get(0);
    results.html('');
    if (appCacheFrame) {
        appCacheFrame.contentWindow.applicationCache.update();
    }
    else {
        $('#content-area').after('<iframe id="appCacheDownloadFrame" src="/wp-includes/offline.html" style="position:absolute;"></iframe>');
    }
 });
});

Making the IFrame Invisible

Assigning a position of “absolute” ensures that the iframe doesn’t consume any screen real estate. Moreover, its offline.html content contains no HTML within the BODY tag, making the iframe essentially invisible. Nonetheless, their inclusion in the containing document still causes the browser to download the manifest and listed resources:

<!DOCTYPE HTML>
<html manifest="GoodFoodTalksManifest.php">
<head>
<title>offline.html</title>
</head>
<body>
</body>
</html>

The <html manifest="GoodFoodTalksManifest.php"> is what causes the manifest and associated resources to be downloaded.

The ApplicationCache Event Hanlder

In the HEAD section of the offline.html file, there is a script that monitors the results of the manifest downloads. There are three events that we are interested in: the cached, error, and noupdate. JQuery’s on() function accepts multiple events, separated by a space, so that one handler may server numerous events. A switch within the handler can select an action based on the event type. Regarding the error event, AppCache errors don’t provide any information, so a generic message is displayed, along with a link to dismiss the message. This is accomplished by calling a JavaScript function as the href target. The results.html(\’\’) is not a page, but a call to the jQuery html() function with an empty string, which is applied to the results DIV. The quotes must be escaped because the entire line is itself a string. Enclosing the call within the void() function cancelled navigation to the link so that the browser doesn’t navigate away from the page.

Since the offline.html page has no direct reference to jQuery, we must employ the parent’s using parent.$. The $ object is passed to the ready() event so that it may be accessed by enclosed functions:

<head>
<title>offline.html</title>

<script type="text/javascript">
parent.$(document).ready(function($) {
  $(window.applicationCache).on('cached error noupdate', function(e) {
     var message = '';
     switch (e.type) { 
       case 'error':
         message = "The AppCache did not download."      + "<br />"
                 + "We'll try again next time you visit." + "<br />"
                 + '<a href="javascript:void(results.html(\'\'))">Click here</a> to dismiss this message and continue.';
         break;
      case 'cached': 
         message = "The AppCache has been successfully installed.";
         break;
      case 'noupdate':
         message = "No changes have been made to the cached files since you last downloaded the AppCache.";
         break;    
     }
     $(parent.results).html(message);
  });
});
</script>
</head>

Conclusion

Despite some limitations, I have found the AppCache to be an extremely useful addition to the HTML5 toolset. Limitations that I’m sure will be stomped out within a few releases as the AppCache specification matures. Until then, we can manage just fine.

thumbnail Rob Gravelle

Rob Gravelle resides in Ottawa, Canada, and has been an IT guru for over 20 years. In that time, Rob has built systems for intelligence-related organizations such as Canada Border Services and various commercial businesses. In his spare time, Rob has become an accomplished music artist with several CDs and digital releases to his credit.

Recommended for you...

Best VR Game Development Platforms
Enrique Corrales
Jul 21, 2022
Best Online Courses to Learn HTML
Ronnie Payne
Jul 7, 2022
Working with HTML Images
Octavia Anghel
Jun 30, 2022
Web 3.0 and the Future Of Web Development
Rob Gravelle
Jun 23, 2022
HTML Goodies Logo

The original home of HTML tutorials. HTMLGoodies is a website dedicated to publishing tutorials that cover every aspect of being a web developer. We cover programming and web development tutorials on languages and technologies such as HTML, JavaScript, and CSS. In addition, our articles cover web frameworks like Angular and React.JS, as well as popular Content Management Systems (CMS) that include WordPress, Drupal, and Joomla. Website development platforms like Shopify, Squarespace, and Wix are also featured. Topics related to solid web design and Internet Marketing also find a home on HTMLGoodies, as we discuss UX/UI Design, Search Engine Optimization (SEO), and web dev best practices.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.