Search code examples
javascriptcross-domainoffline-cachingapplication-cache

Detecting applicationCache viability of remote resource


I am trying to determine if cache (as obtained via applicationCache and HTML5 cache-manifest) is available located on a different domain (local file system vs WWW).

The cache-checking resource (a gateway mechanism, if you will) is located on the local filesystem and is loaded via a webview. This is a requirement that I cannot work around.

Until recently, this gateway local file would check to see if the device is online and redirect to the remote resource using window.location and if the device was not online, it would display a graphic (also locally packaged) that essentially said "You must connect to the internet to use this feature."

However, I just recently implemented offline support on that remote resource. It works. If we have the gateway file just redirect to the remote resource whilst offline, it'll load the remote resource from cache.

There's a possibility that a user may try to use the device whilst offline when they have not yet accessed it via online, so logic needs to be placed in the gateway code to test if the cache exists or not. I am running into cross domain issues, which I expected, but I am not sure how to go about fixing it.

Here is the code I have tried:

if (window.navigator.onLine === false) {
    // See if we're able to reach the content (if it's cached, we'll get HTML, else it'll fail)
    cacheCheck = $.ajax(contentLoc, {async:false});

    // the request failed so we have no cache at all. let's just show the offline graphic.
    if (cacheCheck.status === 0) { // no cache available :(
        $("#launchpage").addClass("offline");
    } else { // we have a cache :)
        redirect();
    }
} else {
    redirect();
}

When I was writing it, I was under the naive hope that the $.ajax() would fetch the cached version (if it existed) and I could just test the returned object to see if the status code returned wasn't an error status code.

However, this does not work as object is returning "Error: NETWORK_ERR: XMLHttpRequest Exception 101"

Is there any other method that I can use to determine whether or not it is safe to redirect? It's a requirement that I display a local image if a redirect would fail (due to no cache)


Solution

  • I have figured out a workaround. If I inject an iframe pointing to the remote resource and check to see if that iframe loads HTML (I specifically check if the tag contains a manifest attribute) it assumes that cache exists and it can perform a redirect.

    If I don't get what I'm expecting, the error graphic displays. Though in my implementation the graphic is always displayed when offline since I have to wait for the iframe to load asynchronously.

    Here is example code to make it work:

    if (window.navigator.onLine === false) {
    // We're offline, so show the offline graphic, in case the future test fails (i.e., no cache available)
        $("#launchpage").addClass("offline");
    
        // Create an iframe pointing to the canvas. If it loads, we have a cache
        $('body').append('<iframe id="offlineTest" src="'+contentLoc+'" style="display:none;" />');
    
        $('#offlineTest').bind('load', function() {
            // See if the result HTML tag has a manifest tag.
            manifest = $("#offlineTest").contents().find('html').attr('manifest');
    
            if (manifest !== undefined) { // cache is available.
                redirect();
            }
        });
    } else {
        redirect();
    }