Question

I'm testing HTML5 offline application. To do that, I'm stopping my local web server (IIS) and open application. It's loaded fine, but it failed as soon as it request server side API method.

I want to prevent that and instead of $.get('/api/method') read data from my local storage. But I can found any facility to understand my application is offline.

if (/* online */) {
  // fire ajax
} else {
  // ask localstorage
}

I tried to use navigation.onLine but it seems to be always true (at least I can see that in Chrome).

Do you have any suggestions?

EDIT: taking into account current answers. Application is clearly understand that it's offline, since it takes resources according to cache.manifest. It's ridiculous to me, that client need to do any kind of tricks and pings. I assume there should be a easy way to check current mode.

Was it helpful?

Solution

One easy way to check is to add a fallback section in your manifest like this:

FALLBACK
/online.js /offline.js

Then in online.js you set a global variable to true, in offline.js you set it to false and you just request online.js by Ajax whenever you plan to do some networking and do whatever processing you need conditionally in the callback. In the meantime, maintain all your app data client side.

An alternative approach is a blocking polyfill for navigator.onLine as suggested by Remy Sharp.

OTHER TIPS

online state could be also checked doing an ajax HEAD request with a timeout and when timeout is reached (or the call returns an error status) you can assume you're working offline (no network capabitlities) and you have to use localstorage instead

In fact, for the sake of state consistency, localstorage should be used as a fallback not only when you're offline, but also when you're online and the specific ajax resource is not temporarily available (e.g. site overload). Of course you will need to make a continuos polling to that resource with regular (or incremental) timeout until it becomes available again.

I was needing the same functionality and after much searching found this function:

http://louisremi.com/2011/04/22/navigator-online-alternative-serverreachable/

Here is the code from the article, just in case the link goes down:

function serverReachable() {
  // IE vs. standard XHR creation
  var x = new ( window.ActiveXObject || XMLHttpRequest )( "Microsoft.XMLHTTP" ),
     s;
  x.open(
      // requesting the headers is faster, and just enough
      "HEAD",
      // append a random string to the current hostname,
      // to make sure we're not hitting the cache
      window.location.href.split("?")[0] + "?" + Math.random(),
      // make a synchronous request
      false
  );
  try {
      x.send();
      s = x.status;
      // Make sure the server is reachable
      return ( s >= 200 && s < 300 || s === 304 );
  } 
  // catch network & other problems
  catch (e) {
     return false;
  }
}

Note that the code above includes a fix by Scott Jehl for working with localhost which is posted lower down in the comments. And here is a link to a jQuery version of the same function:

https://gist.github.com/scottjehl/947084

And the code from that link:

function serverReachable() {
    var s = $.ajax({
           type: "HEAD",
           url: window.location.href.split("?")[0] + "?" + Math.random(),
           async: false
       }).status;
    return s >= 200 && s < 300 || s === 304;
};

I have found this technique to be really effective. Because the request is only for header information it is reasonably fast and it works across all browsers. Great success! :)

I hope other find this as helpful as I did. :)

How about doing some error handling. Like a Try Catch loop.

 try {
    //Run some code here
    }
 catch(err) {
    //Handle errors here
    }

Is it an option to ask localstorage when ajax call fails with a specific error (operation timeout)?

Or since the page (at least partially) is generated with server script you can include a request timestamp (or unique id) on your page with server-side script and put it to localstorage. Then you can see if the page is loaded from cache by checking stored id against the rendered one.

The best option might be to use the error event of the jQuery $.get() function to query localStorage rather than your webserver. This has the benefit of falling back if your server becomes unreachable as well as if the users entire internet is unreachable.

$.get({
  success: //deal with postback from ajax call,
  error: //Whoops no access to server deal with it in a local way
})
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top