just some thoughts about software and other things I like

Check Internet Connection with JavaScript

Offline apps are badass. More importantly, if you can build offline applications properly, that makes you a badass. I'll be covering offline applications in more depth in later posts, here we'll dicuss the basics of how to determine if a client has access to the internet.


Before we get started, you may want to read more about the W3C’s spec on offline web apps, however be aware that this functionality works best in modern web browsers, implementing this with older web browsers may not work as expected, or probably at all.

var online = navigator.onLine;

Alternatively, an XHR request to your own server isn’t that awful of a method for testing your connectivity. Consider that there are more points of failure for an XHR, but if your XHR is flawed when establishing it’s connection then it’d also be flawed during routine use anyhow.

If your site is unreachable for any reason, than your other services running on the same network will likely be unreachable also. That decision is up to you.

I’d recommend not making an XHR request to someone else’s service, even google.com for that matter. Make the request to your server, or not at all.

In your html <head> tag let’s try to load jQuery from Google’s CDN:

<script src='http://www.google.com/jsapi'></script>
<script id='jquery_loader'></script>

In your js file (or possibly still in the <head> if you want):

function loadJQuery() {
  if (navigator.onLine(connected)) {
    google.load("jquery", "1.4.1");
  } else {
    document.getElementById('jquery_loader')
      .src = '/javascripts/jquery.js';
  }
}

Then right before your close </body> tag:

<script>loadJQuery();</script>

Bizarrely enough, the reason this works is because writing to the object’s src attribute calls the browsers parsing engine again, which will have to parse the script tag and thus include the local file if the browser is deemed offline by the prior method.

But why put the script tag at the end of the <body>? This is because without jQuery’s ready() function, we are stuck to emulate the readiness of the DOM, and this would be the best way to do that, the only native option would be the onload attribute of your body tag, but this happens far later in load sequence of your page (just after the reflow and draw).</p>

So what does it mean to be “online”?

There seems to be some confusion around what being “online” means. Consider that the internet is a bunch of networks, however sometimes you’re on a VPN without access to the internet “at-large” or the world wide web. Oftentimes companies have their own networks which have limited connectivity to other external networks, therefore you could be considered “online”. Being online only entails that you are connected to a network, not the availability nor reachability of the services you are trying to connect to.

I wrote the following function (which can be found as a Gist as well) to determine if a particular service or hostname is reachable, ideally it would take an argument that would be the host you want to check while defulting to the window.location.hostname. I’ll extend it to do that, but for now here it is:

function hostReachable() {

  // Handle IE and more capable browsers
  var xhr = new ( window.ActiveXObject || XMLHttpRequest )( "Microsoft.XMLHTTP" );
  var status;

  // Open new request as a HEAD to the root hostname with a random param to bust the cache
  xhr.open( "HEAD", "//" + window.location.hostname + "/?rand=" + Math.floor((1 + Math.random()) * 0x10000), false );

  // Issue request and handle response
  try {
    xhr.send();
    return ( xhr.status >= 200 && xhr.status < 300 || xhr.status === 304 );
  } catch (error) {
    return false;
  }

}