5

There used to exist offline.js for detection of a connection, but that project is no longer maintained. Also, the browser's 'navigator.onLine' property is notoriously unreliable.

What is the best/most up-to-date method to use to actively detect the browser's online state, compatible with modern browsers including mobile device browsers, that can raise various events when the online status changes? Do I need to write this myself, or is that reinventing the wheel?

Note that nobody in my userbase is going to be changing the "Work Offline" setting in the browser in order to go online/offline. Instead, they will be unplugging network cables, disconnecting from wifi networks, driving to locations where no signals are available, etc.

My thought was to simply set up a timeout to repeatedly make AJAX calls to a URL on my server, and simply set an 'online' variable to true/false as well as call online/offline callback functions based on error/success of the AJAX call. Is that the recommended way?

Ryan Griggs
  • 2,457
  • 2
  • 35
  • 58
  • perhaps try with [online/offline events](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/Online_and_offline_events)? though it may be the same as navigator.onLine, which should be reliable in modern browsers according to the [MDN link](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/Online_and_offline_events)? – Malte R Apr 02 '18 at 22:36
  • 1
    @MalteR I think these events also aren't guaranteed to offer a true online/offline status... It sounds more like nobody has bothered to develop a new library for this after the offline.js library was left to die. I wonder why? Am I missing something? – Ryan Griggs Apr 02 '18 at 23:19
  • 1
    @MalteR The events don't work either... – Raz Luvaton Oct 11 '18 at 15:14
  • Did you find anything Ryan? I wrote one myself; with a 'connection service' making constant pings and keeping track of an 'online' property (and behavior subject), and a http interceptor which tries to set the status based on any request to my backend. This is really flaky, but this is how I interpret the browser to be offline, or rather, the backend as unreachable: `(err.status === 0 && err.ok === false && err.name === 'HttpErrorResponse') || err.status === 504`, but I'm pretty sure this is browser/library-dependent. – Vincent Sels Feb 18 '21 at 09:12
  • @VincentSels Yes that's what did too. Just hit a web api and check for errors. – Ryan Griggs Feb 18 '21 at 16:36

3 Answers3

0

simply use

navigator.onLine

see the browser support https://caniuse.com/#feat=online-status

Imal Hasaranga Perera
  • 9,683
  • 3
  • 51
  • 41
  • I'm not sure why you are saying it is not working anymore, this is a well accepted feature, see the browser support – Imal Hasaranga Perera Oct 12 '18 at 08:39
  • If you tested it you would see that it’s not working – Raz Luvaton Oct 12 '18 at 10:25
  • just tested in chrome Version 69.0.3497.100 – Imal Hasaranga Perera Oct 12 '18 at 11:02
  • How did you test it by turning on and off the wifi or by the DevTools?, in the DevTool it will work but not if you're actually turn on/off your connection – Raz Luvaton Oct 13 '18 at 21:21
  • oh, I understand your problem, this will not trigger anything which means if you need to constantly monitor the state of your connection you need to have this inside a interval and give around 10 second delay. and then console out the value, I did disableing the wifi directly not by dev tool – Imal Hasaranga Perera Oct 16 '18 at 06:51
  • 1
    I tested it with different laptops/users with the same Chrome browser version (on Ubuntu) and for some reason it works for some laptops and doesn't work with others. – eli-bd Nov 12 '18 at 09:53
0

Use

`var wentOffline, wentOnline;
 function handleConnectionChange(event){
    if(event.type == "offline"){
        console.log("You lost connection.");
        wentOffline = new Date(event.timeStamp);
    }
    if(event.type == "online"){
        console.log("You are now back online.");
        wentOnline = new Date(event.timeStamp);
        console.log("You were offline for " + (wentOnline — wentOffline) / 1000 + "seconds.");
    }
}
window.addEventListener('online', handleConnectionChange);
window.addEventListener('offline', handleConnectionChange);`

Check the post: https://medium.com/@MateMarschalko/online-and-offline-events-with-javascript-d424bec8f43

Benjamin Udu
  • 1
  • 1
  • 2
0

I worked on a similar implementation and this was my solution using setInterval and fetch API. There will be 2 functions, first function will run for every 30 seconds checking internet connection. A flag variable is set to true which will control the function execution. In case of disconnection, the second function will be invoked to call fetch API for every 5 seconds. If successfully connected, the flag is set to true so the first function can be executed again for every 30 seconds and the interval is cleared.

doesConnectionExist: function() {
setInterval(function () {
if(flag === true){
let randomNum = Math.round(Math.random() * 10000);
let url = "test.js?rand=";
const response = fetch(url + randomNum)
                .then(function () {
                    clearInterval(interval);
                })
                .catch(function () {
                     console.log("You are currently offline.");
                     interval = setInterval(function () { checkForConnectivity(); }, 5000);
                });
}
}, 30000);
}

checkConnectivity: function() {
flag = false;
let randomNum = Math.round(Math.random() * 10000);
let url = "test.js?rand=";
const response = fetch(url + randomNum)
                .then(function () {
                    console.log("Your Internet connection was restored.");
                     clearInterval(interval);
                     flag = true;
})
.catch(function () {
                    return null;
                });
};
  • I like the idea of polling faster when the connection is down, so you will detect the reconnect quicker. – Ryan Griggs Aug 28 '21 at 15:46
  • You can try calling a local js file instead of an external website and the response time would be be quicker and in my case, it returned within few ms. I have updated the code as well. – JavaScript Bee Aug 30 '21 at 14:18