Détecter que la connexion Internet est hors ligne?

246

Comment détecter que la connexion Internet est hors ligne en JavaScript?

Daniel Silveira
la source
Si vous pouvez ou utilisez déjà des websockets - les websockets ont un événement Close qui doit être appelé si l'utilisateur a perdu la connexion au serveur.
Simon

Réponses:

135

Vous pouvez déterminer que la connexion est perdue en effectuant des demandes XHR ayant échoué .

L'approche standard consiste à réessayer la demande plusieurs fois. S'il ne passe pas, avertissez l'utilisateur de vérifier la connexion et échouez sans problème .

Sidenote: Pour mettre l'application entière dans un état "hors ligne", cela peut entraîner beaucoup de travail de gestion des erreurs. Les connexions sans fil peuvent aller et venir, etc. Donc, votre meilleur pari peut être de simplement échouer gracieusement, de conserver le données, et alerter l'utilisateur .. leur permettant éventuellement de résoudre le problème de connexion s'il y en a un, et de continuer à utiliser votre application avec une bonne dose de pardon.

Sidenote: Vous pouvez vérifier la connectivité d'un site fiable comme Google, mais cela peut ne pas être entièrement utile car il suffit d'essayer de faire votre propre demande, car même si Google peut être disponible, votre propre application peut ne pas l'être et vous allez toujours devez gérer votre propre problème de connexion. Essayer d'envoyer un ping à Google serait un bon moyen de confirmer que la connexion Internet elle-même est en panne, donc si ces informations vous sont utiles, cela pourrait valoir la peine.

Sidenote : L' envoi d'un ping pourrait être réalisé de la même manière que vous feriez n'importe quelle sorte de demande ajax bidirectionnelle, mais l'envoi d'un ping à google, dans ce cas, poserait des défis. Tout d'abord, nous aurions les mêmes problèmes interdomaines que ceux rencontrés lors des communications Ajax. Une option consiste à configurer un proxy côté serveur, dans lequel nousping Google (ou n'importe quel site), et renvoyons les résultats du ping à l'application. Ceci est un catch-22parce que si la connexion Internet est réellement le problème, nous ne pourrons pas accéder au serveur, et si le problème de connexion ne concerne que notre propre domaine, nous ne pourrons pas faire la différence. D'autres techniques interdomaines pourraient être essayées, par exemple, en incorporant une iframe dans votre page qui pointe vers google.com, puis en interrogeant l'iframe pour la réussite / l'échec (examinez le contenu, etc.). L'intégration d'une image peut ne pas vraiment nous dire quoi que ce soit, car nous avons besoin d'une réponse utile du mécanisme de communication afin de tirer une bonne conclusion sur ce qui se passe. Encore une fois, déterminer l'état de la connexion Internet dans son ensemble peut être plus difficile que cela en vaut la peine. Vous devrez pondérer ces options pour votre application spécifique.

keparo
la source
84
Le "Sidenote" répété sonne comme Dwight Schrute disant "Question ..." :-)
Brian Kelly
19
Pourquoi "catch-22" en gras?
codingbear
33
Maintenant, en 2012, vous pouvez vérifier la variable navigator.onLine;)
João Pinto Jerónimo
13
navigator.online/offline n'est pas fiable non plus, pour les mêmes raisons. Voir stackoverflow.com/questions/3181080/…
Efran Cobisi
17
Vous voudrez peut-être consulter Offline.js , une bibliothèque open-source conçue à cet effet.
Adam
51

IE 8 prendra en charge la propriété window.navigator.onLine .

Mais bien sûr, cela n'aide pas avec d'autres navigateurs ou systèmes d'exploitation. Je prédis que d'autres fournisseurs de navigateurs décideront également de fournir cette propriété étant donné l'importance de connaître l'état en ligne / hors ligne dans les applications Ajax.

Jusqu'à ce que cela se produise, XHR ou une demande Image()or <img>peut fournir quelque chose de proche de la fonctionnalité souhaitée.

Mise à jour (2014/11/16)

Les principaux navigateurs prennent désormais en charge cette propriété, mais vos résultats varient.

Citation de la documentation Mozilla :

Dans Chrome et Safari, si le navigateur n'est pas en mesure de se connecter à un réseau local (LAN) ou à un routeur, il est hors ligne; toutes les autres conditions reviennent true. Donc, même si vous pouvez supposer que le navigateur est hors ligne lorsqu'il renvoie unfalse valeur, vous ne pouvez pas supposer qu'une vraie valeur signifie nécessairement que le navigateur peut accéder à Internet. Vous pourriez obtenir des faux positifs, comme dans les cas où l'ordinateur exécute un logiciel de virtualisation doté d'adaptateurs Ethernet virtuels qui sont toujours «connectés». Par conséquent, si vous voulez vraiment déterminer l'état en ligne du navigateur, vous devez développer des moyens supplémentaires de vérification.

Dans Firefox et Internet Explorer, le basculement du navigateur en mode hors ligne envoie une falsevaleur. Toutes les autres conditions renvoient une truevaleur.

Grant Wagner
la source
5
navigator.onLine fait partie de HTML5 - d'autres navigateurs ont déjà des versions de développement qui le fournissent - il est déjà disponible dans Firefox 3 aujourd'hui.
olliej
-mais malheureusement pas disponible dans les versions antérieures d'IE, que nous devons souvent prendre en charge.
keparo
22
navigator.onLine affiche l'état du navigateur et non la connexion réelle. Donc, vous pouvez avoir votre navigateur configuré pour être en ligne, mais cela échouerait en fait parce que la connexion est coupée. navigator.onLine ne sera faux que si le navigateur est configuré pour une navigation hors ligne.
5
si je désactive le WI-FI sur mon Nexus7, la page indique toujours que navigator.onLine est VRAI. Mauvais ...
walv
42

Presque tous les principaux navigateurs prennent désormais en charge la window.navigator.onLinepropriété et les événements correspondants onlineet offlinewindow:

window.addEventListener('online', () => console.log('came online'));
window.addEventListener('offline', () => console.log('came offline'));

Essayez de configurer votre système ou votre navigateur en mode hors ligne / en ligne et vérifiez la console ou la window.navigator.onLinepropriété pour les changements de valeur. Vous pouvez également le tester sur ce site Web .

Notez cependant cette citation de la documentation de Mozilla :

Dans Chrome et Safari, si le navigateur n'est pas en mesure de se connecter à un réseau local (LAN) ou à un routeur, il est hors ligne; toutes les autres conditions reviennent true. Ainsi, même si vous pouvez supposer que le navigateur est hors ligne lorsqu'il renvoie une falsevaleur , vous ne pouvez pas supposer qu'une truevaleur signifie nécessairement que le navigateur peut accéder à Internet . Vous pourriez obtenir des faux positifs, comme dans les cas où l'ordinateur exécute un logiciel de virtualisation doté d'adaptateurs Ethernet virtuels qui sont toujours «connectés». Par conséquent, si vous voulez vraiment déterminer l'état en ligne du navigateur, vous devez développer des moyens supplémentaires de vérification.

Dans Firefox et Internet Explorer, le basculement du navigateur en mode hors ligne envoie une falsevaleur. Jusqu'à Firefox 41, toutes les autres conditions renvoient une truevaleur; depuis Firefox 41, sous OS X et Windows, la valeur suivra la connectivité réseau réelle.

(L'accent est le mien)

Cela signifie que si window.navigator.onLineest false(ou vous obtenez un offlineévénement), vous êtes assuré d'avoir aucune connexion Internet.

Si c'est le cas true(ou si vous obtenez un onlineévénement), cela signifie seulement que le système est connecté à un réseau, au mieux. Cela ne signifie pas que vous avez accès à Internet par exemple. Pour vérifier cela, vous devrez toujours utiliser l'une des solutions décrites dans les autres réponses.

J'avais initialement l'intention de publier cela comme une mise à jour de la réponse de Grant Wagner , mais cela semblait trop éditer, d'autant plus que la mise à jour 2014 n'était pas déjà de lui .

Didier L
la source
Meilleure réponse. Merci.
vibs2006
1
J'ai récemment eu l'occasion de travailler un peu sur le comportement hors ligne. Les événements sont géniaux à utiliser, MAIS le safari ios créera des problèmes. Lorsque vous désactivez Internet sur votre téléphone, les événements hors ligne / en ligne seront retardés jusqu'à 2 secondes et cela peut être problématique pour des raisons de rendu visuel, car vous ne pouvez pas prédire l'avenir. C'est juste quelque chose que je voulais mentionner et qui pourrait aider quelqu'un.
TeeJaay
38

Il y a un certain nombre de façons de le faire:

  • Demande AJAX à votre propre site Web. Si cette demande échoue, il y a de fortes chances que la connexion soit en cause. La documentation JQuery contient une section sur la gestion des demandes AJAX ayant échoué . Méfiez-vous de la même politique d'origine lorsque vous faites cela, ce qui peut vous empêcher d'accéder à des sites en dehors de votre domaine.
  • Vous pouvez mettre un onerrordans un img, comme

    <img src='http://www.example.com/singlepixel.gif' 
          onerror='alert("Connection dead");' />

    Cette méthode pourrait également échouer si l'image source est déplacée / renommée, et serait généralement un choix inférieur à l'option ajax.

Il existe donc plusieurs façons différentes d'essayer de détecter cela, aucune parfaite, mais en l'absence de la possibilité de sortir du bac à sable du navigateur et d'accéder directement à l'état de connexion Internet de l'utilisateur, elles semblent être les meilleures options.

ConroyP
la source
36
 if(navigator.onLine){
  alert('online');
 } else {
  alert('offline');
 }
Edmhs
la source
11
Il retourne toujours VRAI si sur le navigateur.
Slavcho
2
Eh bien d'abord, j'essayais de désactiver UNIQUEMENT le LAN, mais il retournait toujours VRAI. Ainsi, lorsque j'ai désactivé tous les réseaux (LAN2, Virtual Box, etc.), cela a renvoyé FAUX.
Slavcho
3
Cette réponse duplique plusieurs réponses existantes d'il y a 3 ans.
JasonMArcher
2
il ne vérifie pas la connectivité Internet, il vérifie uniquement la connectivité LAN seul
Suganth G
A travaillé pour moi en HTML 5, JavaScript, en mac book (en utilisant le wifi) même travaillé en mobile. mais le problème est que lorsque le wifi est activé, il retourne VRAI à chaque fois que je désactive le wifi vice-versa.
S.Yadav
11

L'API HTML5 Application Cache spécifie navigator.onLine, qui est actuellement disponible dans les versions bêtas IE8, WebKit (par exemple Safari), et est déjà pris en charge dans Firefox 3

olliej
la source
11

Vous pouvez utiliser $ .ajax () de » errorfonction de rappel qui incendies si la demande échoue. Si textStatusest égal à la chaîne "timeout", cela signifie probablement que la connexion est rompue:

function (XMLHttpRequest, textStatus, errorThrown) {
  // typically only one of textStatus or errorThrown 
  // will have info
  this; // the options for this ajax request
}

Du doc :

Erreur : une fonction à appeler si la demande échoue. La fonction reçoit trois arguments: l'objet XMLHttpRequest, une chaîne décrivant le type d'erreur qui s'est produite et un objet d'exception facultatif, le cas échéant. Les valeurs possibles pour le deuxième argument (outre null) sont "timeout", "error", "notmodified" et "parsererror". Ceci est un événement Ajax

Ainsi, par exemple:

 $.ajax({
   type: "GET",
   url: "keepalive.php",
   success: function(msg){
     alert("Connection active!")
   },
   error: function(XMLHttpRequest, textStatus, errorThrown) {
       if(textStatus == 'timeout') {
           alert('Connection seems dead!');
       }
   }
 });
karim79
la source
9

Comme l'a dit olliej, l'utilisation de la navigator.onLinepropriété du navigateur est préférable à l'envoi de requêtes réseau et, en conséquence, avec developer.mozilla.org/En/Online_and_offline_events , elle est même prise en charge par les anciennes versions de Firefox et IE.

Récemment, le WHATWG a spécifié l'ajout des événements onlineet offline, au cas où vous auriez besoin de réagir surnavigator.onLine changements.

Veuillez également prêter attention au lien publié par Daniel Silveira qui souligne que se fier à ces signaux / propriétés pour la synchronisation avec le serveur n'est pas toujours une bonne idée.


la source
MISE À JOUR: En 2015, il semble fonctionner dans la plupart des navigateurs, voir le graphique et l' article de
Olga
8
window.navigator.onLine

est ce que vous recherchez, mais peu de choses à ajouter, d'abord, si c'est quelque chose sur votre application que vous souhaitez continuer à vérifier (comme pour voir si l'utilisateur se met soudainement hors ligne, ce qui corrige dans ce cas la plupart du temps, alors vous besoin d'écouter le changement également), pour cela vous ajoutez un écouteur d'événements à la fenêtre pour détecter tout changement, pour vérifier si l'utilisateur se déconnecte, vous pouvez faire:

window.addEventListener("offline", 
  ()=> console.log("No Internet")
);

et pour vérifier si en ligne:

window.addEventListener("online", 
  ()=> console.log("Connected Internet")
);
Alireza
la source
2
Vous devez être prudent avec onLine. Les navigateurs définissent l'état d'être en ligne très différemment. Jetez un œil à developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine .
Andreas Baumgart
1
Votre réponse est fausse. La propriété «onLine» n'a rien à voir avec la connectivité Internet. Voir la référence ci-dessus à propos de l'API Web.
Alexandre V.
7

J'ai dû faire une application web (basée sur ajax) pour un client qui travaille beaucoup avec les écoles, ces écoles ont souvent une mauvaise connexion internet J'utilise cette fonction simple pour détecter s'il y a une connexion, ça marche très bien!

J'utilise CodeIgniter et Jquery:

function checkOnline() {
    setTimeout("doOnlineCheck()", 20000);
}

function doOnlineCheck() {
    //if the server can be reached it returns 1, other wise it times out
    var submitURL = $("#base_path").val() + "index.php/menu/online";

    $.ajax({
        url : submitURL,
        type : "post",
        dataType : "msg",
        timeout : 5000,
        success : function(msg) {
            if(msg==1) {
                $("#online").addClass("online");
                $("#online").removeClass("offline");
            } else {
                $("#online").addClass("offline");
                $("#online").removeClass("online");
            }
            checkOnline();
        },
        error : function() {
            $("#online").addClass("offline");
            $("#online").removeClass("online");
            checkOnline();
        }
    });
}
THEO
la source
6

un appel ajax vers votre domaine est le moyen le plus simple de détecter si vous êtes hors ligne

$.ajax({
      type: "HEAD",
      url: document.location.pathname + "?param=" + new Date(),
      error: function() { return false; },
      success: function() { return true; }
   });

c'est juste pour vous donner le concept, il faut l'améliorer.

Par exemple, erreur = 404 devrait toujours signifier que vous êtes en ligne

harishr
la source
4

Je pense que c'est une manière très simple.

var x = confirm("Are you sure you want to submit?");
if (x) {
  if (navigator.onLine == true) {
    return true;
  }
  alert('Internet connection is lost');
  return false;
}
return false;
Prakash Pazhanisamy
la source
onLine ne signifie pas qu'il existe une connexion Internet. Selon developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine if the browser is not able to connect to a local area network (LAN) or a router, it is offline; all other conditions return true
Shmuel Kamensky
2

Je cherchais une solution côté client pour détecter si Internet était en panne ou mon serveur en panne. Les autres solutions que j'ai trouvées semblaient toujours dépendre d'un fichier ou d'une image de script tiers, qui ne me semblait pas résister à l'épreuve du temps. Un script ou une image hébergée externe pourrait changer à l'avenir et entraîner l'échec du code de détection.

J'ai trouvé un moyen de le détecter en recherchant un xhrStatus avec un code 404. De plus, j'utilise JSONP pour contourner la restriction CORS. Un code d'état autre que 404 indique que la connexion Internet ne fonctionne pas.

$.ajax({
    url:      'https://www.bing.com/aJyfYidjSlA' + new Date().getTime() + '.html',
    dataType: 'jsonp',
    timeout:  5000,

    error: function(xhr) {
        if (xhr.status == 404) {
            //internet connection working
        }
        else {
            //internet is down (xhr.status == 0)
        }
    }
});
chemin d'avenir
la source
2
Cela ne fonctionne pas au 10-5-2016, je ne sais pas pourquoi ne voulez pas que le temps des autres soit gaspillé.
Bren
Je ne pense pas que cela fonctionnera pour les erreurs de demande interdites et mauvaises :)
Faisal Naseer
1

Mon chemin.

<!-- the file named "tt.jpg" should exist in the same directory -->

<script>
function testConnection(callBack)
{
    document.getElementsByTagName('body')[0].innerHTML +=
        '<img id="testImage" style="display: none;" ' +
        'src="tt.jpg?' + Math.random() + '" ' +
        'onerror="testConnectionCallback(false);" ' +
        'onload="testConnectionCallback(true);">';

    testConnectionCallback = function(result){
        callBack(result);

        var element = document.getElementById('testImage');
        element.parentNode.removeChild(element);
    }    
}
</script>

<!-- usage example -->

<script>
function myCallBack(result)
{
    alert(result);
}
</script>

<a href=# onclick=testConnection(myCallBack);>Am I online?</a>
non lié
la source
1

Le problème de certaines méthodes comme navigator.onLineest qu'elles ne sont pas compatibles avec certains navigateurs et versions mobiles, une option qui m'a beaucoup aidé était d'utiliser la XMLHttpRequestméthode classique et de prévoir également le cas possible où le fichier a été stocké dans le cache avec une réponse XMLHttpRequest.statussupérieure à 200 et moins de 304.

Voici mon code:

 var xhr = new XMLHttpRequest();
 //index.php is in my web
 xhr.open('HEAD', 'index.php', true);
 xhr.send();

 xhr.addEventListener("readystatechange", processRequest, false);

 function processRequest(e) {
     if (xhr.readyState == 4) {
         //If you use a cache storage manager (service worker), it is likely that the
         //index.php file will be available even without internet, so do the following validation
         if (xhr.status >= 200 && xhr.status < 304) {
             console.log('On line!');
         } else {
             console.log('Offline :(');
         }
     }
}
Vladimir Salguero
la source
0

Il y a 2 réponses pour deux sénarios différents: -

  1. Si vous utilisez JavaScript sur un site Web (c'est-à-dire; ou toute partie frontale) La façon la plus simple de le faire est:

    <h2>The Navigator Object</h2>
    
    <p>The onLine property returns true if the browser is online:</p>
    
    <p id="demo"></p>
    
    <script>
      document.getElementById("demo").innerHTML = "navigator.onLine is " + navigator.onLine;
    </script>

  2. Mais si vous utilisez js côté serveur (c.-à-d. Nœud, etc.), vous pouvez déterminer que la connexion est perdue en effectuant des requêtes XHR ayant échoué.

    L'approche standard consiste à réessayer la demande plusieurs fois. S'il ne passe pas, avertissez l'utilisateur de vérifier la connexion et échouez sans problème.

Rishabh Anand
la source
0

tête de requête en erreur de requête

$.ajax({
    url: /your_url,
    type: "POST or GET",
    data: your_data,
    success: function(result){
      //do stuff
    },
    error: function(xhr, status, error) {

      //detect if user is online and avoid the use of async
        $.ajax({
            type: "HEAD",
            url: document.location.pathname,
            error: function() { 
              //user is offline, do stuff
              console.log("you are offline"); 
              }
         });
    }   
});
Kareem
la source
-1

Voici un extrait d'un utilitaire d'aide que j'ai. Il s'agit de javascript à espace de noms:

network: function() {
    var state = navigator.onLine ? "online" : "offline";
    return state;
}

Vous devriez l'utiliser avec la détection de méthode, sinon lancer une méthode «alternative» pour le faire. Le temps approche à grands pas quand ce sera tout ce qui sera nécessaire. Les autres méthodes sont des hacks.

Peter Mortensen
la source