Check If Internet Connection Exists in JavaScript

by kirupa   |   14 September 2013

If there is ever a moment when you need your internet connection to work, there is a very good chance it is at that very moment your internet connection will fail. This is one of those universally accepted truths...I think. Anyway, building an app or a site whose functionality relies on an internet connection being present is tricky. You can't always guarantee that an internet connection will be available when your app requires it, and this is especially true on mobile devices when your internet connectivity might be flaky.

To avoid situations where something you create misbehaves because an internet connection isn't available, you need a way to detect whether an internet connection exists. The best part is that it isn't very hard to do.

Take a look at the following example:

Click on the Check connection! text. If you have an active internet connection, you will see a dialog telling you that a connection exists:

connection exists

If you don't have an internet connection (something you can temporarily simulate by unplugging your network cable or turning off your wireless), you will see a dialog that says that an internet connection does not exist:

connection doesn't exist

This crazy-awesome functionality is made possible using a little bit of JavaScript and a simple XMLHttpRequest technique. In this article, you will learn all about it.

Onwards!

Detecting the Internet Connection

The way I check if an internet connection exists pretty simple. There is some code that attempts to access a file that exists on the internet. If we can access that file, this means an internet connection exists:

connection exists

If we can't access that file, this means an internet connection doesn't exist or something like a firewall or Nicholas Cage is preventing your app from connecting to the internet:

no connection

The code for all of what I just described looks as follows:

function doesConnectionExist() {
    var xhr = new XMLHttpRequest();
    var file = "http://www.yoursite.com/somefile.png";
    var randomNum = Math.round(Math.random() * 10000);
    
    xhr.open('HEAD', file + "?rand=" + randomNum, false);
    
    try {
    	xhr.send();
    	
	    if (xhr.status >= 200 && xhr.status < 304) {
	        return true;
	    } else {
	        return false;
	    }
    } catch (e) {
    	return false;
    }
}

The doesConnectionExist function returns a true if an internet connection exists. This function returns a false if an internet connection does not exist. To use this code in your own site or app, the only thing you need to do is change the URL specified for the file variable:

var file = "http://www.yoursite.com/somefile.png";

Change the URL to point to any file that you know exists on your own server. That's all there is to it. To see a full working version of this code, check out the source for the example you saw earlier from the following location.

The Code Explained

In the previous section, you saw the code that makes all of this work. You also received a very simple explanation as to what the code does. In this section, let's look through each line of our code in detail and get the real explanation...starting at the top:

var xhr = new XMLHttpRequest();

The first thing we do is create the xhr variable and initialize it to a new XMLHttpRequest object. This object contains all of the properties and methods you need for sending or getting data from across the internet without requiring you to refresh your page.

 

The next three lines are related, so let's look at them together:

var file = "http://www.yoursite.com/somefile.png";
var randomNum = Math.round(Math.random() * 10000);

xhr.open('HEAD', file + "?rand=" + randomNum, false);

The file and randomNum variables help you to construct a URL that points to a known file on the internet. You see these variables being used when we call open on our xhr object:

var file = "http://www.yoursite.com/somefile.png";
var randomNum = Math.round(Math.random() * 10000);

xhr.open('HEAD', file + "?rand=" + randomNum, false);

The open method is pretty interesting, so let's look at it in more detail.

The Open Method

The open method allows us to construct a request. Think of this is formally defining the parameters you want in order to send your request off to the internet. The open method (in this variation) takes three arguments:

  1. The type of HTTP method to use
  2. The URL to send the request to
  3. Whether the request will be made asynchronously

HTTP Method

Our HTTP method is going to be HEAD. There are several HTTP methods available that you can specify, but we want to use a method that simply checks on a file without actually downloading it. The HEAD method fits that requirement.

The URL

The URL we specify is the path to the file that we want to check on. This URL is a combination of the file and randomNum variables that you saw earlier. Then end result is a string that might look as follows:

http://www.kirupa.com/blank.png?rand=6544

The random number tagged on as part of the URL is there to prevent a cached result from being returned.

Asynchronous Much?

The last argument we specify is whether we want this request to be done in the background asynchronously or whether we want this to block all other code from executing and run synchronously. Whether you specify true (asynchronous) or false (synchronous) depends entirely on your app.

If your application simply cannot proceed further without first checking whether an internet connection exists, you should specify false. If you are checking for the internet connection in a more passive way and your application doesn't demand an answer immediately, specify true.

In our example, we specified false.

 

So far, all we've done is create our XMLHttpRequest object and constructed our HTTP request. Things really start moving in the next chunk of code:

try {
	xhr.send();
	
    if (xhr.status >= 200 && xhr.status < 304) {
        return true;
    } else {
        return false;
    }
} catch (e) {
	return false;
}

We wrap all of this code inside a try/catch statement. The reason has to do with the xhr.send() line:

try {
	xhr.send();
	
    if (xhr.status >= 200 && xhr.status < 304) {
        return true;
    } else {
        return false;
    }
} catch (e) {
	return false;
}

When the send method executes, the HTTP request you constructed earlier in open is actually transmitted. If you do not have an internet connection that allows this request to fly away, the send method throws an exception. At this point, your app would instantly crash if you didn't use the try/catch statement to anticipate and react to this mini-meltdown.

If an internet connection does exist, your send method transmits the message and returns an HTTP status code (xhr.status). Looking at the various status codes goes well beyond the scope of this article, but as long as your status code falls within 200 and 303, you are in good shape and this entire function returns a true.

That check is handled by the following highlighted lines:

try {
	xhr.send();
	
    if (xhr.status >= 200 && xhr.status < 304) {
        return true;
    } else {
        return false;
    }
} catch (e) {
	return false;
}

If your status code goes outside of that range, nobody really knows what is going on. To be safe, our code returns a false to indicate that the connection doesn't exist. It is very likely be that the file you specified as part of your request doesn't exist and needs to be altered. It could be that something else is preventing your connection from succeeding. If you see false being returned consistently, that is a sign that you need to troubleshoot your connection.

After writing this article, several people asked me why I don't use the navigator.onLine property to check whether a connection exists or not. After all, this property's sole reason for existing is to tell you...whether a connection exists or not. It seems like the obvious choice, right? Well, not quite! Here is why I don't like to use it for what we are trying to do.

What we are doing is checking if we have an internet connection. The reason we are doing this is to actually connect to the internet and do something with some remote data. Simply checking if we have a valid connection isn't adequate. I could be connected to a local network and not have access to the broader internet. I could be in a virtual machine with a virtual network adapter that always shows an active connection...even if such a connection doesn't actually exist. You may have a firewall that causes problems. There are many cases where your browser will falsely report a connection exists, but the navigator.onLine property will return true.

By making a web request like this article describes, there is no ambiguity on whether your page can connect to the internet. That's why I prefer the XHR approach as opposed to the navigator.onLine property.

Conclusion

More and more of your sites and apps store state in a remote location. Having an internet connection at all times when using your phone or computer or whatever is no longer a luxury for many parts of the world. It is a necessity. Despite that, we (and your users) always manage to get ourselves into situations where an internet connection might not always exist. I'm looking at you Mammoth Caves.

For those moments when your site or app doesn't have an internet connection that it desperately relies on, this code provides you with a basic solution for how to start dealing with it.

Need Help?

If you have questions, need some assistance on this topic, or just want to chat - post in the comments below or drop by our friendly forums (where you have a lot more formatting options) and post your question. There are a lot of knowledgeable and witty people who would be happy to help you out. Plus, we have a large collection of smileys you can use

Share

Did you enjoy reading this and found it useful? If so, please share it with your friends:

If you didn't like it, I always like to hear how I can do better next time. Please feel free to contact me directly at kirupa[at]kirupa.com.

Cheers!

Kirupa Chinnathambi

 

Add Your Comment (or post on the Forums)

blog comments powered by Disqus

Creating high-quality content is a team effort that takes a boatload of time. If you found what you see here helpful, please consider sending a small tip:

While tipping is entirely optional, we'll be your bestest friend forever if you do.

More Details & Options