web-dev-qa-db-fra.com

Comment détecter les événements en ligne/hors ligne sur plusieurs navigateurs?

J'essaie de détecter avec précision le moment où le navigateur se déconnecte, à l'aide des événements en ligne et hors ligne de HTML5.

Voici mon code:

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

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

Cela fonctionne bien lorsque je clique sur "Travailler hors connexion" sur Firefox ou IE, mais cela fonctionne un peu au hasard lorsque je débranche le fil. 

Quel est le meilleur moyen de détecter ce changement? J'aimerais éviter de répéter des appels ajax avec des délais d'attente.

95
Pierre Duplouy

Les éditeurs de navigateurs ne peuvent s'entendre sur la définition d'une connexion hors connexion. Certains navigateurs ont une fonctionnalité Travail hors connexion, qu’ils considèrent comme distincte du manque d’accès au réseau, ce qui, encore une fois, est différent de l’accès à Internet. Le tout est en désordre. Certains éditeurs de navigateurs mettent à jour l'indicateur navigator.onLine lorsque l'accès réseau réel est perdu, d'autres non.

De la spec:

Retourne false si l'agent utilisateur est définitivement hors ligne (déconnecté de le réseau). Renvoie true si l'utilisateur l'agent peut être en ligne.

Les événements en ligne et hors ligne sont déclenché lorsque la valeur de cet attribut changements.

L'attribut navigator.onLine doit renvoie false si l'agent utilisateur le fera pas contacter le réseau lorsque l'utilisateur suit des liens ou quand un script demande une page distante (ou sait qu'une telle tentative échouerait.), et doit retourne vrai sinon.

Enfin, les notes de spécifications:

Cet attribut est par nature non fiable. Un ordinateur peut être connecté à un réseau sans avoir Accès Internet.

62
Rebecca

Les principaux fournisseurs de navigateurs diffèrent sur ce que signifie "hors connexion".

Chrome et Safari détectent automatiquement le passage "hors ligne" - ce qui signifie que les événements et les propriétés "en ligne" se déclenchent automatiquement lorsque vous débranchez le câble réseau.

Firefox (Mozilla), Opera et IE adoptent une approche différente et vous considèrent comme "en ligne" à moins que vous ne choisissiez explicitement le "Mode hors connexion" dans le navigateur, même si vous ne disposez pas d'une connexion réseau.

Il existe des arguments valables pour le comportement de Firefox/Mozilla, décrits dans les commentaires de ce rapport de bogue:

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

Mais pour répondre à la question, vous ne pouvez pas vous fier aux événements/propriétés en ligne/hors ligne pour détecter s’il existe réellement une connectivité réseau.

Au lieu de cela, vous devez utiliser d'autres approches.

La section "Notes" de cet article de Mozilla Developer fournit des liens vers deux méthodes alternatives:

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

"Si l'API n'est pas implémentée dans le navigateur, vous pouvez utiliser d'autres signaux pour déterminer si vous êtes hors ligne, y compris l'écoute des événements d'erreur AppCache et les réponses de XMLHttpRequest"

Ceci est lié à un exemple de l'approche "écoute des événements d'erreur AppCache":

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

... et un exemple de l'approche "écoute des échecs XMLHttpRequest":

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

HTH, -- Tchad

31
thewoolleyman

Aujourd'hui, une bibliothèque JavaScript open source fait ce travail: elle s'appelle Offline.js .

Afficher automatiquement les indications en ligne/hors ligne à vos utilisateurs.

https://github.com/HubSpot/offline

Assurez-vous de vérifier le fichier _ README COMPLET . Il contient des événements auxquels vous pouvez vous accrocher.

Voici un page de test . C'est beau/a une belle interface utilisateur au fait! :)

Offline.js Simulate UI est un plug-in Offline.js cela vous permet de tester comment vos pages répondent à différents états de connectivité sans avoir à utiliser les méthodes de force brute pour désactiver votre connectivité réelle.

17

Le meilleur moyen qui fonctionne maintenant sur tous les principaux navigateurs est le script suivant:

(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

15
tmaximini

Depuis récemment, navigator.onLine affiche la même chose sur tous les principaux navigateurs et est donc utilisable.

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

Les versions les plus anciennes qui supportent cela correctement sont: Firefox 41 , IE 9, Chrome 14 et Safari 5. 

Actuellement, cela représente presque tout le spectre des utilisateurs, mais vous devez toujours vérifier ce que les utilisateurs de votre page ont de fonctionnalités.

Avant FF 41, false n'était affiché que si l'utilisateur mettait le navigateur manuellement en mode hors connexion. Dans IE 8, la propriété se trouvait sur body, au lieu de window.

source: caniuse

8
Haroen Viaene

L'attribut window.navigator.onLine et ses événements associés ne sont actuellement pas fiables sur certains navigateurs Web ( en particulier Firefox desktop ) comme l'a dit @Junto. déclenchez les événements offline et online appropriés:

// Global variable somewhere in your app to replicate the 
// window.navigator.onLine variable (it 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
      }
    }
  });
}

Vous pouvez l'utiliser comme ceci:

// 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
}

Pour écouter les événements hors ligne et en ligne (avec l'aide de jQuery):

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

navigator.onLine est un désordre

Je fais face à cela lorsque j'essaie de faire un appel ajax au serveur.

Il existe plusieurs situations possibles lorsque le client est hors ligne: 

  • le délai d'appels ajax et vous recevez une erreur
  • l'appel ajax renvoie le succès, mais le msg est null
  • l'appel ajax n'est pas exécuté car le navigateur le décide (peut-être que navigator.onLine devient faux après un certain temps)

La solution que j'utilise est de contrôler le statut moi-même avec javascript. Je pose les conditions d'un appel réussi, dans tous les autres cas, je suppose que le client est hors ligne .

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);
          }
        });
      }
6
Toolkit

En HTML5, vous pouvez utiliser la propriété navigator.onLine. Regardez ici:

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

Votre comportement actuel est probablement aléatoire, car javascript prépare uniquement la variable "browser" et sait ensuite si vous êtes hors ligne et en ligne, mais il ne vérifie pas la connexion réseau.

Faites-nous savoir si c'est ce que vous recherchez.

Sincères amitiés,

5
Trefex

Veuillez trouver le module require.js que j'ai écrit pour 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;
});

S'il vous plaît lire ce blog et laissez-moi savoir vos pensées. http://zen-and-art-of-programming.blogspot.com/2014/04/html-5-offline-application-development.html Il contient un exemple de code utilisant offline.js pour détecter quand client est hors ligne.

2
Srihari Sridharan

J'utilise l'option FALLBACK du manifeste de cache HTML5 pour vérifier si mon application html5 est en ligne ou hors ligne en:

FALLBACK:
/online.txt /offline.txt

Dans la page html, javascript est utilisé pour lire le contenu du fichier txt en ligne/hors ligne:

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

En mode hors connexion, le script lit le contenu du fichier offline.txt . Selon le texte des fichiers, vous pouvez détecter si la page Web est en ligne ou hors ligne. 

2
Marcel Scholte

vous pouvez détecter facilement de manière cross-browser hors ligne comme ci-dessous 

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; }
   });

vous pouvez remplacer yoururl.com par document.location.pathname.

Le nœud de la solution consiste à essayer de vous connecter à votre nom de domaine. Si vous ne pouvez pas vous connecter, vous êtes hors ligne. fonctionne navigateur croisé.

1
harishr

Utilisation du corps du document:

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

Utilisation de l'événement Javascript:

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

  function updateOnlineStatus(event) {

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

  }

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

});

Référence:
Corps de document: événement en ligne
Javascript-event: événements en ligne et hors ligne

Pensées supplémentaires:
Pour expédier autour de "la connexion réseau est différente de la connexion Internet" Problème de la méthode ci-dessus: Vous pouvez vérifier une fois la connexion Internet avec ajax au démarrage de l'application et configurer un mode en ligne/hors ligne. Créez un bouton de reconnexion pour que l'utilisateur se connecte. Et ajoutez à chaque demande ajax échouée une fonction qui renvoie l'utilisateur en mode hors connexion.

0
Milingu Kilu

Voici ma solution.

Testé avec IE, Opera, Chrome, FireFox, Safari, en tant qu'application Phonegap WebApp sur IOS 8 et en tant qu'application Phonegap WebApp sur Android 4.4.2

Cette solution ne fonctionne pas avec FireFox sur localhost.

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

onlineCheck.js (chemin du fichier: "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 (chemin du fichier: "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 (chemin du fichier: "root"):

<?php echo 'true'; ?> 
0
JoJoWhatsUp

eh bien, vous pouvez essayer le plug-in javascript qui peut surveiller la connexion du navigateur en temps réel et avertir l'utilisateur si Internet ou la connexion des navigateurs avec Internet s'est arrêtée.

Plugin Javascript Wiremonkey Et la démo que vous pouvez trouver ici

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

0
Ry Van