How to detect online/offline event cross-browser?

2019-01-02 17:32发布

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.

15条回答
旧人旧事旧时光
2楼-- · 2019-01-02 18:16

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,

查看更多
余生无你
3楼-- · 2019-01-02 18:18

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

Chrome and Safari will detect when you go "offline" automatically - meaning that "online" events and properties will fire automatically when you unplug your network cable.

Firefox (Mozilla), 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

查看更多
永恒的永恒
4楼-- · 2019-01-02 18:19

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'; ?> 
查看更多
低头抚发
5楼-- · 2019-01-02 18:20

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.

查看更多
其实,你不懂
6楼-- · 2019-01-02 18:20

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.

查看更多
与风俱净
7楼-- · 2019-01-02 18:21

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

查看更多
登录 后发表回答