118

I'm trying to accurately detect when the browser goes offline, using the HTML5 online and offline events.

Here's my code:

<script>
    // FIREFOX
    $(window).bind("online", applicationBackOnline); 
    $(window).bind("offline", applicationOffline);

    //IE
    window.onload = function() {
        document.body.ononline = IeConnectionEvent;
        document.body.onoffline = IeConnectionEvent;
    } 
</script>

It works fine when I just hit "Work offline" on either Firefox or IE, but it's kind of randomly working when I actually unplug the wire.

What's the best way to detect this change? I'd like to avoid repeating ajax calls with timeouts.

4
  • 2
    I agree with Trefex, but I would also like to add that connection detection support is shoddy at best for most apps: just because the wire is unplugged does not immediately constitute a lost connection. Relying on a method that doesn't physically test whether the connection is open cannot really guarantee accurate results.
    – mattbasta
    Commented Jul 6, 2010 at 7:32
  • Thanks for your advice. So you would recommend the Ajax method? ie. keep on sending XHR calls with timeouts? Commented Jul 6, 2010 at 7:57
  • Firefox's (and IE's and Opera's) implementation is wrong. See my comment to that effect here: bugzilla.mozilla.org/show_bug.cgi?id=654579#c9 Commented Mar 11, 2012 at 9:30
  • 4
    You may want to check out Offline.js, an open-source library built for just this purpose.
    – Adam
    Commented Oct 27, 2013 at 22:32

16 Answers 16

73

Currently in 2011, the various browser vendors cannot agree on how to define offline. Some browsers have a Work Offline feature, which they consider separate to a lack of network access, which again is different to internet access. The whole thing is a mess. Some browser vendors update the navigator.onLine flag when actual network access is lost, others don't.

From the spec:

Returns false if the user agent is definitely offline (disconnected from the network). Returns true if the user agent might be online.

The events online and offline are fired when the value of this attribute changes.

The navigator.onLine attribute must return false if the user agent will not contact the network when the user follows links or when a script requests a remote page (or knows that such an attempt would fail), and must return true otherwise.

Finally, the spec notes:

This attribute is inherently unreliable. A computer can be connected to a network without having Internet access.

10
  • 24
    Only Chrome sets navigator.onLine properly when connectivity is lost. Both Safari and Firefox never set the flag to false if you remove the internet connection.
    – chovy
    Commented Oct 4, 2011 at 0:36
  • 2
    @chovy and how about now? I lately tested it in Firefox/Chrome and got the expected results, seeing that the flag is being set, when I turn off and on the internet connection.. Commented Nov 27, 2015 at 12:45
  • 13
    Today 1/31/2017 I opened OSX Chrome 55.0.2883.95, Safari 10.0.3, and FF 50.1.0. All of the window.navigator.onLine seems to work great when I stayed on my network, but removed the cord from my router. They all correctly detected offline.
    – nycynik
    Commented Jan 31, 2017 at 17:10
  • 4
    navigator.onLine is supported across all major browsers (and has been for some time): caniuse.com/#feat=online-status
    – rlueder
    Commented Mar 30, 2018 at 17:59
  • @RafaelLüder Correct as of today, but this answer was written in Jan 2011!
    – Rebecca
    Commented Apr 3, 2018 at 12:47
34

The major browser vendors differ on what "offline" means.

Chrome, Safari, and Firefox (since version 41) will detect when you go "offline" automatically - meaning that "online" events and properties will fire automatically when you unplug your network cable.

Mozilla Firefox (before version 41), Opera, and IE take a different approach, and consider you "online" unless you explicitly pick "Offline Mode" in the browser - even if you don't have a working network connection.

There are valid arguments for the Firefox/Mozilla behavior, which are outlined in the comments of this bug report:

https://bugzilla.mozilla.org/show_bug.cgi?id=654579

But, to answer the question - you can't rely on the online/offline events/property to detect if there is actually network connectivity.

Instead, you must use alternate approaches.

The "Notes" section of this Mozilla Developer article provides links to two alternate methods:

https://developer.mozilla.org/en/Online_and_offline_events

"If the API isn't implemented in the browser, you can use other signals to detect if you are offline including listening for AppCache error events and responses from XMLHttpRequest"

This links to an example of the "listening for AppCache error events" approach:

http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-appcache

...and an example of the "listening for XMLHttpRequest failures" approach:

http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-xml-http-request

HTH, -- Chad

1
  • 2
    Starting with Firefox 41: updates this property when the OS reports a change in network connectivity on Windows, Linux, and OS X. (according to the docs you've mentioned). So it's not only offline if you're browsing with the browser "Offline mode"
    – dude
    Commented Jan 20, 2017 at 9:50
17

Today there's an open source JavaScript library that does this job: it's called Offline.js.

Automatically display online/offline indication to your users.

https://github.com/HubSpot/offline

Be sure to check the full README. It contains events that you can hook into.

Here's a test page. It's beautiful/has a nice feedback UI by the way! :)

Offline.js Simulate UI is an Offline.js plug-in that allows you to test how your pages respond to different connectivity states without having to use brute-force methods to disable your actual connectivity.

2
  • 2
    The library actually works by fetching local favicon repeatedly under the hood. In my opinion, the library is too "big" and has too many features; the main trick is just fetching favicon repeatedly. Commented Oct 10, 2016 at 12:07
  • 1
    Doesn't detect offline when I unplug the network cable
    – poshest
    Commented Jul 26, 2019 at 9:55
16

The best way which works now on all Major Browsers is the following Script:

(function () {
    var displayOnlineStatus = document.getElementById("online-status"),
        isOnline = function () {
            displayOnlineStatus.innerHTML = "Online";
            displayOnlineStatus.className = "online";
        },
        isOffline = function () {
            displayOnlineStatus.innerHTML = "Offline";
            displayOnlineStatus.className = "offline";
        };

    if (window.addEventListener) {
        /*
            Works well in Firefox and Opera with the 
            Work Offline option in the File menu.
            Pulling the ethernet cable doesn't seem to trigger it.
            Later Google Chrome and Safari seem to trigger it well
        */
        window.addEventListener("online", isOnline, false);
        window.addEventListener("offline", isOffline, false);
    }
    else {
        /*
            Works in IE with the Work Offline option in the 
            File menu and pulling the ethernet cable
        */
        document.body.ononline = isOnline;
        document.body.onoffline = isOffline;
    }
})();

Source: http://robertnyman.com/html5/offline/online-offline-events.html

2
  • 6
    As the comments in the code itself clearly state - it does not work in Firefox/Chrome if you unplug the ethernet cable or turn wifi off.
    – Manish
    Commented Feb 21, 2014 at 12:05
  • 1
    I tried visiting the "Source" link and disconnected ethernet cable, it showed "You are offline" in IE, but not in Firefox/Chrome for me(using latest version of all browsers). May be I am missing something?
    – Manish
    Commented Feb 24, 2014 at 10:05
15

Since recently, navigator.onLine shows the same on all major browsers, and is thus useable.

if (navigator.onLine) {
  // do things that need connection
} else {
  // do things that don't need connection
}

The oldest versions that support this in the right way are: Firefox 41, IE 9, Chrome 14 and Safari 5.

Currently this will represent almost the whole spectrum of users, but you should always check what the users of your page have of capabilities.

Previous to FF 41, it would only show false if the user put the browser manually in offline mode. In IE 8, the property was on the body, instead of window.

source: caniuse

13

The window.navigator.onLine attribute and its associated events are currently unreliable on certain web browsers (especially Firefox desktop) as @Junto said, so I wrote a little function (using jQuery) that periodically checks the network connectivity status and raise the appropriate offline and online events:

// Global variable somewhere in your app to replicate the 
// window.navigator.onLine variable (this last is not modifiable). It prevents
// the offline and online events to be triggered if the network
// connectivity is not changed
var IS_ONLINE = true;

function checkNetwork() {
  $.ajax({
    // Empty file in the root of your public vhost
    url: '/networkcheck.txt',
    // We don't need to fetch the content (I think this can lower
    // the server's resources needed to send the HTTP response a bit)
    type: 'HEAD',
    cache: false, // Needed for HEAD HTTP requests
    timeout: 2000, // 2 seconds
    success: function() {
      if (!IS_ONLINE) { // If we were offline
        IS_ONLINE = true; // We are now online
        $(window).trigger('online'); // Raise the online event
      }
    },
    error: function(jqXHR) {
      if (jqXHR.status == 0 && IS_ONLINE) {
        // We were online and there is no more network connection
        IS_ONLINE = false; // We are now offline
        $(window).trigger('offline'); // Raise the offline event
      } else if (jqXHR.status != 0 && !IS_ONLINE) {
        // All other errors (404, 500, etc) means that the server responded,
        // which means that there are network connectivity
        IS_ONLINE = true; // We are now online
        $(window).trigger('online'); // Raise the online event
      }
    }
  });
}

You can use it like this:

// Hack to use the checkNetwork() function only on Firefox 
// (http://stackoverflow.com/questions/5698810/detect-firefox-browser-with-jquery/9238538#9238538)
// (But it may be too restrictive regarding other browser
// who does not properly support online / offline events)
if (!(window.mozInnerScreenX == null)) {
    window.setInterval(checkNetwork, 30000); // Check the network every 30 seconds
}

To listen to the offline and online events (with the help of jQuery):

$(window).bind('online offline', function(e) {
  if (!IS_ONLINE || !window.navigator.onLine) {
    alert('We have a situation here');
  } else {
    alert('Battlestation connected');
  }
});
0
8

navigator.onLine is a mess

I face this when trying to make an ajax call to the server.

There are several possible situations when the client is offline:

  • the ajax call timouts and you receive error
  • the ajax call returns success, but the msg is null
  • the ajax call is not executed because browser decides so (may be this is when navigator.onLine becomes false after a while)

The solution I am using is to control the status myself with javascript. I set the condition of a successful call, in any other case I assume the client is offline. Something like this:

var offline;
pendingItems.push(item);//add another item for processing
updatePendingInterval = setInterval("tryUpdatePending()",30000);
tryUpdatePending();

    function tryUpdatePending() {

        offline = setTimeout("$('#offline').show()", 10000);
        $.ajax({ data: JSON.stringify({ items: pendingItems }), url: "WebMethods.aspx/UpdatePendingItems", type: "POST", dataType: "json", contentType: "application/json; charset=utf-8",
          success: function (msg) {
            if ((!msg) || msg.d != "ok")
              return;
            pending = new Array(); //empty the pending array
            $('#offline').hide();
            clearTimeout(offline);
            clearInterval(updatePendingInterval);
          }
        });
      }
0
5

In HTML5 you can use the navigator.onLine property. Look here:

http://www.w3.org/TR/offline-webapps/#related

Probably your current behavior is random as the javascript only ready the "browser" variable and then knows if you're offline and online, but it doesn't actually check the Network Connection.

Let us know if this is what you're looking for.

Kind Regards,

6
  • Thanks for your help Trefex. I changed my code, and now only check the navigator.onLine property, however I get the same behavior as before. Please have a look at mattbasta's comment. Commented Jul 6, 2010 at 7:59
  • Hi Pedro, I agree with mattbasta but I hoped it would work for you :) I would definitely use the Ajax method to query some URL that you know is always up and then you'd know if a connection is lost or not. On another note, why do you require the accurate detection of the online / offline status ? Maybe if we'd know more, there would be another solution for your issue. Let us know,
    – Trefex
    Commented Jul 6, 2010 at 8:42
  • 1
    Ok, thanks :) I just thought it'd be better for the user if the application was able to auto-detect a change in connectivity (no need to manually enable the offline mode in FF or IE). This way, when the application goes offline, it will use its local cache instead of querying the server. I found this post from John Resig, which pretty much explains why this doesn't work: ejohn.org/blog/offline-events Commented Jul 6, 2010 at 9:20
  • Thank you for that blog post. Relly in depth analysis and right to the point. I think what you want to achieve it's best if you query some server (maybe your own) and then switch to local cache when there is x number of timeouts. What do you think ?
    – Trefex
    Commented Jul 6, 2010 at 9:32
  • Yeah I guess that is the best option - given the current state of the art. I hope that all browser will eventually be able to detect the actual loss of connection by themselves: using navigator.onLine is pretty simple and this shouldn't be more complex. Don't you think? Commented Jul 6, 2010 at 10:03
3

Please find the require.js module that I wrote for Offline.

define(['offline'], function (Offline) {
    //Tested with Chrome and IE11 Latest Versions as of 20140412
    //Offline.js - http://github.hubspot.com/offline/ 
    //Offline.js is a library to automatically alert your users 
    //when they've lost internet connectivity, like Gmail.
    //It captures AJAX requests which were made while the connection 
    //was down, and remakes them when it's back up, so your app 
    //reacts perfectly.

    //It has a number of beautiful themes and requires no configuration.
    //Object that will be exposed to the outside world. (Revealing Module Pattern)

    var OfflineDetector = {};

    //Flag indicating current network status.
    var isOffline = false;

    //Configuration Options for Offline.js
    Offline.options = {
        checks: {
            xhr: {
                //By default Offline.js queries favicon.ico.
                //Change this to hit a service that simply returns a 204.
                url: 'favicon.ico'
            }
        },

        checkOnLoad: true,
        interceptRequests: true,
        reconnect: true,
        requests: true,
        game: false
    };

    //Offline.js raises the 'up' event when it is able to reach
    //the server indicating that connection is up.
    Offline.on('up', function () {
        isOffline = false;
    });

    //Offline.js raises the 'down' event when it is unable to reach
    //the server indicating that connection is down.
    Offline.on('down', function () {
        isOffline = true;
    });

    //Expose Offline.js instance for outside world!
    OfflineDetector.Offline = Offline;

    //OfflineDetector.isOffline() method returns the current status.
    OfflineDetector.isOffline = function () {
        return isOffline;
    };

    //start() method contains functionality to repeatedly
    //invoke check() method of Offline.js.
    //This repeated call helps in detecting the status.
    OfflineDetector.start = function () {
        var checkOfflineStatus = function () {
            Offline.check();
        };
        setInterval(checkOfflineStatus, 3000);
    };

    //Start OfflineDetector
    OfflineDetector.start();
    return OfflineDetector;
});

Please read this blog post and let me know your thoughts. http://zen-and-art-of-programming.blogspot.com/2014/04/html-5-offline-application-development.html It contains a code sample using offline.js to detect when the client is offline.

0
3

you can detect offline cross-browser way easily like below

var randomValue = Math.floor((1 + Math.random()) * 0x10000)

$.ajax({
      type: "HEAD",
      url: "http://yoururl.com?rand=" + randomValue,
      contentType: "application/json",
      error: function(response) { return response.status == 0; },
      success: function() { return true; }
   });

you can replace yoururl.com by document.location.pathname.

The crux of the solution is, try to connect to your domain name, if you are not able to connect - you are offline. works cross browser.

7
  • Sometimes no, like my api's homepage is a 404
    – Ben Aubin
    Commented Apr 26, 2015 at 16:37
  • Not just my api's, but lots of sites don't have a home page. Check to make sure the status code and data received is null, that is the best way to make sure it's not just a normal, expectable error
    – Ben Aubin
    Commented Apr 26, 2015 at 18:20
  • @penne12 I had used this answer and it is working in my web-api as well
    – algos
    Commented Apr 26, 2015 at 19:28
  • It works, but comes with unexpected consequences, as I explained (error means a error or an error not in the 200, sometimes the sever will be down, too)
    – Ben Aubin
    Commented Apr 26, 2015 at 19:46
  • if the server is down, then we r offline, thats what we r trying to detect here, right
    – harishr
    Commented Apr 27, 2015 at 4:17
2

I use the FALLBACK option in the HTML5 cache manifest to check if my html5 app is online or offline by:

FALLBACK:
/online.txt /offline.txt

In the html page i use javascript tot read the contents of the online/offline txt file:

<script>$.get( "urlto/online.txt", function( data ) {
$( ".result" ).html( data );
alert( data );
});</script>

When offline the script will read the contents of the offline.txt. Based on the text in the files you can detect if the webpage is online of offline.

1

Using Document Body:

<body ononline="onlineConditions()" onoffline="offlineConditions()">(...)</body>

Using Javascript Event:

window.addEventListener('load', function() {

  function updateOnlineStatus() {

    var condition = navigator.onLine ? "online" : "offline";
    if( condition == 'online' ){
        console.log( 'condition: online')
    }else{
        console.log( 'condition: offline')
    }

  }

  window.addEventListener('online',  updateOnlineStatus );
  window.addEventListener('offline', updateOnlineStatus );

});

Reference:
Document-Body: ononline Event
Javascript-Event: Online and offline events

Additional Thoughts:
To ship around the "network connection is not the same as internet connection" Problem from the above methods: You can check the internet connection once with ajax on the application start and configure an online/offline mode. Create a reconnect button for the user to go online. And add on each failed ajax request a function that kick the user back into the offline mode.

1
  • 1
    This won't work: window.addEventListener('online', updateOnlineStatus(event) ); because you are calling the updateOnlineStatus() function immediately. It should be window.addEventListener('online', updateOnlineStatus ); Commented Feb 27, 2018 at 13:28
0

Here is my solution.

Tested with IE, Opera, Chrome, FireFox, Safari, as Phonegap WebApp on IOS 8 and as Phonegap WebApp on Android 4.4.2

This solution isn't working with FireFox on localhost.

=================================================================================

onlineCheck.js (filepath: "root/js/onlineCheck.js ):

var isApp = false;

function onLoad() {
        document.addEventListener("deviceready", onDeviceReady, false);
}

function onDeviceReady() {
    isApp = true;
    }


function isOnlineTest() {
    alert(checkOnline());
}

function isBrowserOnline(no,yes){
    //Didnt work local
    //Need "firefox.php" in root dictionary
    var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttp');
    xhr.onload = function(){
        if(yes instanceof Function){
            yes();
        }
    }
    xhr.onerror = function(){
        if(no instanceof Function){
            no();
        }
    }
    xhr.open("GET","checkOnline.php",true);
    xhr.send();
}

function checkOnline(){

    if(isApp)
    {
        var xhr = new XMLHttpRequest();
        var file = "http://dexheimer.cc/apps/kartei/neu/dot.png";

        try {
            xhr.open('HEAD', file , false); 
            xhr.send(null);

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

        tmpIsOnline = navigator.onLine;

        if(tmpIsOnline || tmpIsOnline == "undefined")
        {
            try{
                //Didnt work local
                //Need "firefox.php" in root dictionary
                var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttp');
                xhr.onload = function(){
                    tmpIsOnline = true;
                }
                xhr.onerror = function(){
                    tmpIsOnline = false;
                }
                xhr.open("GET","checkOnline.php",false);
                xhr.send();
            }catch (e){
                tmpIsOnline = false;
            }
        }
        return tmpIsOnline;

    }
}

=================================================================================

index.html (filepath: "root/index.html"):

<!DOCTYPE html>
<html>


<head>
    ...

    <script type="text/javascript" src="js/onlineCheck.js" ></script>

    ...

</head>

...

<body onload="onLoad()">

...

    <div onclick="isOnlineTest()">  
        Online?
    </div>
...
</body>

</html>

=================================================================================

checkOnline.php (filepath: "root"):

<?php echo 'true'; ?> 
0

well, you can try the javascript plugin which can monitor the browser connection in real time and notifies the user if internet or the browsers connection with the internet went down.

Wiremonkey Javascript plugin and the demo you can find here

http://ryvan-js.github.io/

0
<html>
<head>
<script>
     window.addEventListener("online",function(){
    document.getElementById('note').
    innerHTML='you are online';
    });
    window.addEventListener("offline",function(){
    document.getElementById('note').
    innerHTML='you are offline';
    });
</script>
</head>
<body>
   <div id="note"> </div>
</body>
</html>
1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Sep 8, 2022 at 7:15
0

Simplest implementation is

window.addEventListener("online", () => this.isOnline(true), false);
window.addEventListener("offline", () => this.isOnline(false), false); 

isOnline = (status) => {
if (status) toast.success('Online')
if (!status) toast.warn('Offline')
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.