Detectar a conexão com a Internet está offline?

246

Como detectar se a conexão com a Internet está offline em JavaScript?

Daniel Silveira
fonte
Se você pode ou já usa websockets - os websockets têm um evento Close que deve ser chamado se o usuário perder a conexão com o servidor.
Simon

Respostas:

135

Você pode determinar que a conexão é perdida fazendo solicitações XHR com falha .

A abordagem padrão é repetir a solicitação algumas vezes. Se não for aprovado, alerte o usuário para verificar a conexão e falhe normalmente .

Nota: Para colocar o aplicativo inteiro em um estado "offline", você pode levar a muito trabalho sujeito a erros no tratamento do estado. As conexões sem fio podem ir e vir, etc. Portanto, sua melhor aposta é falhar normalmente, preservar o dados e alertar o usuário. permitindo que, eventualmente, corrija o problema de conexão, se houver, e continue usando o aplicativo com uma boa quantia de perdão.

Nota: Você pode verificar um site confiável como o google para obter conectividade, mas isso pode não ser totalmente útil, apenas tentando fazer sua própria solicitação, porque, embora o Google esteja disponível, seu próprio aplicativo pode não estar, e você ainda vai precisa lidar com seu próprio problema de conexão. Tentar enviar um ping para o google seria uma boa maneira de confirmar que a conexão com a Internet está inoperante; portanto, se essas informações forem úteis para você, vale a pena.

Nota : O envio de um ping pode ser alcançado da mesma maneira que você faria qualquer tipo de solicitação de ajax bidirecional, mas enviar um ping para o google, nesse caso, apresentaria alguns desafios. Primeiro, teríamos os mesmos problemas entre domínios que normalmente são encontrados na comunicação do Ajax. Uma opção é configurar um proxy do lado do servidor, no qual, na verdade, pesquisamos no pingGoogle (ou em qualquer site) e devolvemos os resultados do ping ao aplicativo. Este é um prendedor-22porque se a conexão à Internet for realmente o problema, não conseguiremos acessar o servidor e, se o problema de conexão estiver apenas em nosso próprio domínio, não poderemos dizer a diferença. Outras técnicas entre domínios podem ser tentadas, por exemplo, incorporando um iframe em sua página que aponte para google.com e, em seguida, pesquisando o iframe para obter sucesso / falha (examine o conteúdo etc.). A incorporação de uma imagem pode não nos dizer nada, porque precisamos de uma resposta útil do mecanismo de comunicação para tirar uma boa conclusão sobre o que está acontecendo. Novamente, determinar o estado da conexão à Internet como um todo pode ser mais complicado do que vale a pena. Você terá que ponderar essas opções para seu aplicativo específico.

keparo
fonte
84
As repetidas "sidenote" soa como Dwight Schrute dizendo "Pergunta ..." :-)
Brian Kelly
19
Por que "catch-22" está em negrito?
codingbear
33
Agora em 2012 você pode conferir a variável navigator.onLine;)
João Pinto Jerónimo
13
navigator.online/offline também não é confiável, pelas mesmas razões. Veja stackoverflow.com/questions/3181080/…
Efran Cobisi
17
Você pode conferir o Offline.js , uma biblioteca de código aberto criada para esse fim.
Adam
51

O IE 8 suportará a propriedade window.navigator.onLine .

Mas é claro que isso não ajuda em outros navegadores ou sistemas operacionais. Prevejo que outros fornecedores de navegadores decidirão fornecer essa propriedade também, dada a importância de conhecer o status online / offline nos aplicativos Ajax.

Até que isso aconteça, o XHR ou um Image()ou <img>request podem fornecer algo próximo à funcionalidade desejada.

Atualização (16/11/2014)

Os principais navegadores agora oferecem suporte a essa propriedade, mas seus resultados variam.

Citação da documentação do Mozilla :

No Chrome e Safari, se o navegador não conseguir se conectar a uma rede local (LAN) ou a um roteador, ele estará offline; todas as outras condições retornam true. Portanto, embora você possa presumir que o navegador está offline quando retorna um falsevalor, não é possível assumir que um valor verdadeiro significa necessariamente que o navegador pode acessar a Internet. Você pode obter falsos positivos, como nos casos em que o computador está executando um software de virtualização que possui adaptadores Ethernet virtuais que estão sempre "conectados". Portanto, se você realmente deseja determinar o status online do navegador, deve desenvolver meios adicionais para verificação.

No Firefox e no Internet Explorer, alternar o navegador para o modo offline envia um falsevalor. Todas as outras condições retornam um truevalor.

Grant Wagner
fonte
5
O navigator.onLine faz parte do HTML5 - outros navegadores já possuem versões de desenvolvimento que o fornecem - já está disponível no Firefox 3 hoje.
olliej
-mas infelizmente não está disponível nas versões anteriores do IE, às quais geralmente é necessário oferecer suporte.
keparo 10/10/08
22
navigator.onLine mostra o estado do navegador e não a conexão real. Portanto, você pode ter seu navegador definido como on-line, mas na verdade falharia porque a conexão estava inoperante. navigator.onLine só será falso se o navegador estiver definido para navegação offline.
5
se eu desligar o WI-FI no meu Nexus7, a página ainda informa que navigator.onLine é VERDADEIRO. Bad ...
walv
42

Quase todos os principais navegadores agora suportam a window.navigator.onLinepropriedade e os eventos correspondentes onlinee offlinewindow:

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

Tente configurar o sistema ou o navegador no modo offline / online e verifique o console ou a window.navigator.onLinepropriedade quanto a alterações de valor. Você também pode testá-lo neste site .

Observe, no entanto, esta citação da documentação do Mozilla :

No Chrome e Safari, se o navegador não conseguir se conectar a uma rede local (LAN) ou a um roteador, ele estará offline; todas as outras condições retornam true. Portanto, embora você possa supor que o navegador esteja offline quando retornar um falsevalor , não será possível assumir que um truevalor significa necessariamente que o navegador pode acessar a Internet . Você pode estar obtendo falsos positivos, como nos casos em que o computador está executando um software de virtualização que possui adaptadores Ethernet virtuais que estão sempre "conectados". Portanto, se você realmente deseja determinar o status online do navegador, deve desenvolver meios adicionais para verificação.

No Firefox e no Internet Explorer, alternar o navegador para o modo offline envia um falsevalor. Até o Firefox 41, todas as outras condições retornam um truevalor; desde o Firefox 41, no OS X e Windows, o valor seguirá a conectividade de rede real.

(a ênfase é minha)

Isso significa que, se window.navigator.onLinefor false(ou você receber um offlineevento), é garantido que você não tem conexão com a Internet.

trueNo entanto, se for (ou você receber um onlineevento), isso significa apenas que o sistema está conectado a alguma rede. Isso não significa que você tenha acesso à Internet, por exemplo. Para verificar isso, você ainda precisará usar uma das soluções descritas nas outras respostas.

Inicialmente, pretendia postar isso como uma atualização da resposta de Grant Wagner , mas parecia uma edição muito grande, especialmente considerando que a atualização de 2014 já não era dele .

Didier L
fonte
Melhor resposta. Obrigado.
vibs2006
1
Recentemente, tive a oportunidade de trabalhar um pouco no comportamento offline. Os eventos são ótimos de usar, mas o ios safari cria problemas. Quando você liga a Internet no telefone, os eventos offline / online são atrasados ​​em até 2 segundos e podem ser problemáticos por razões de renderização visual, pois você não pode prever o futuro. Isso é apenas algo que eu queria mencionar e pode ajudar alguém.
TeeJaay
38

Existem várias maneiras de fazer isso:

  • Solicitação AJAX para o seu próprio site. Se essa solicitação falhar, há uma boa chance de a conexão estar com defeito. A documentação do JQuery possui uma seção sobre como manipular pedidos AJAX com falha . Cuidado com a mesma política de origem ao fazer isso, o que pode impedir você de acessar sites fora do seu domínio.
  • Você pode colocar onerrorum img, como

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

    Esse método também pode falhar se a imagem de origem for movida / renomeada e geralmente seria uma opção inferior à opção ajax.

Portanto, existem várias maneiras diferentes de tentar detectar isso, nenhuma perfeita, mas, na ausência da capacidade de sair da caixa de proteção do navegador e acessar diretamente o status da conexão de rede do usuário, elas parecem ser as melhores opções.

ConroyP
fonte
36
 if(navigator.onLine){
  alert('online');
 } else {
  alert('offline');
 }
Edmhs
fonte
11
Retorna sempre TRUE se estiver no navegador.
Slavcho
2
Bem, primeiro eu estava tentando desativar ONLY LAN, mas estava sempre retornando VERDADEIRO. Então, quando eu desabilitei todas as redes (LAN2, Virtual Box etc.), ele retornou FALSE.
Slavcho
3
Esta resposta duplica várias respostas existentes de 3 anos antes.
JasonMArcher
2
a sua não verificação da conectividade internet, marcando a conectividade LAN sozinho
Suganth G
Trabalhei para mim em HTML 5, JavaScript, em mac book (usando wifi) e até trabalhei em dispositivos móveis. mas o problema é: quando o wifi nele retorna VERDADEIRO cada vez que eu desligo o wifi vice-versa.
S.Yadav
11

A API do cache de aplicativos HTML5 especifica navigator.onLine, que está disponível atualmente no IE8 betas, no WebKit (por exemplo, Safari), e já é suportado no Firefox 3

olliej
fonte
11

Você pode usar o retorno de chamada de $ .ajax ()error , que é acionado se a solicitação falhar. Se for textStatusigual à string "timeout", provavelmente significa que a conexão está interrompida:

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

Do documento :

Erro : Uma função a ser chamada se a solicitação falhar. A função recebe três argumentos: O objeto XMLHttpRequest, uma sequência que descreve o tipo de erro que ocorreu e um objeto de exceção opcional, se houver. Os valores possíveis para o segundo argumento (além de nulo) são "timeout", "error", "notmodified" e "parsererror". Este é um evento do Ajax

Então, por exemplo:

 $.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
fonte
9

Como olliej disse, navigator.onLineé preferível usar a propriedade do navegador do que enviar solicitações de rede e, de acordo com developer.mozilla.org/En/Online_and_offline_events , ele é compatível com versões antigas do Firefox e IE.

Recentemente, o WHATWG especificou a adição dos eventos onlinee offline, caso você precise reagir às navigator.onLinealterações.

Por favor, preste atenção também no link postado por Daniel Silveira, que aponta que confiar nesses sinais / propriedades para sincronizar com o servidor nem sempre é uma boa ideia.


fonte
UPDATE: A partir de 2015 parece estar funcionando na maioria dos navegadores, ver gráfico caniuse e artigo
Olga
8
window.navigator.onLine

é o que você procura, mas há poucas coisas a serem adicionadas aqui, primeiro, se é algo no seu aplicativo que você deseja verificar (gostaria de ver se o usuário fica subitamente offline, o que é correto nesse caso na maioria das vezes, então você também é necessário escutar a alteração). Para isso, você adiciona um ouvinte de evento à janela para detectar qualquer alteração. Para verificar se o usuário fica offline, você pode:

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

e para verificar se online:

window.addEventListener("online", 
  ()=> console.log("Connected Internet")
);
Alireza
fonte
2
Você tem que ter cuidado com onLine. Os navegadores definem o estado de estar online de maneira muito diferente. Dê uma olhada em developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine .
Andreas Baumgart
1
Sua resposta está errada. A propriedade 'onLine' não tem nada a ver com conectividade com a Internet. Veja a referência acima sobre a API da Web.
Alexandre V.
7

Eu tive que fazer um aplicativo da Web (baseado em Ajax) para um cliente que trabalha muito com escolas, essas escolas geralmente têm uma conexão ruim à Internet. Eu uso essa função simples para detectar se há uma conexão, funciona muito bem!

Eu uso CodeIgniter e 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
fonte
6

uma chamada ajax para o seu domínio é a maneira mais fácil de detectar se você está offline

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

isto é apenas para lhe dar o conceito, ele deve ser aprimorado.

Por exemplo, erro = 404 ainda deve significar que você está online

harishr
fonte
4

Eu acho que é uma maneira muito simples.

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
fonte
onLine não significa que há uma conexão com a internet. De acordo com developer.mozilla.org/pt-BR/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

Eu estava procurando uma solução do lado do cliente para detectar se a Internet estava inoperante ou se meu servidor estava inoperante. As outras soluções que encontrei sempre pareciam depender de um arquivo ou imagem de script de terceiros, que para mim não pareciam resistir ao teste do tempo. Um script ou imagem hospedada externa pode mudar no futuro e causar falha no código de detecção.

Eu encontrei uma maneira de detectá-lo procurando um xhrStatus com um código 404. Além disso, eu uso o JSONP para ignorar a restrição do CORS. Um código de status diferente de 404 mostra que a conexão à Internet não está funcionando.

$.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)
        }
    }
});
caminho do futuro
fonte
2
Isso não funciona no dia 05/10/2016, não sei por que simplesmente não queremos que o tempo de outras pessoas seja desperdiçado.
Bren
Eu não acho que por isso vai trabalhar para erros de solicitação proibidos e más :)
Faisal Naseer
1

O meu caminho.

<!-- 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>
unxed
fonte
1

O problema de alguns métodos navigator.onLineé que eles não são compatíveis com alguns navegadores e versões móveis, uma opção que me ajudou muito foi usar o XMLHttpRequestmétodo clássico e também prever o possível caso de o arquivo ser armazenado em cache com resposta XMLHttpRequest.statusmaior que 200 e menos que 304.

Aqui está o meu código:

 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
fonte
0

Existem 2 respostas para dois senarios diferentes: -

  1. Se você estiver usando JavaScript em um site (por exemplo, ou qualquer parte do front-end), a maneira mais simples de fazer isso é:

    <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. Mas se você estiver usando js no lado do servidor (ou seja, nó etc.), poderá determinar que a conexão será perdida fazendo solicitações XHR com falha.

    A abordagem padrão é tentar novamente a solicitação algumas vezes. Se não for aprovado, alerte o usuário para verificar a conexão e falhe normalmente.

Rishabh Anand
fonte
0

cabeça de solicitação no erro de solicitação

$.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
fonte
-1

Aqui está um trecho de um utilitário auxiliar que eu tenho. Este é o javascript no namespace:

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

Você deve usá-lo com a detecção de método, para disparar uma maneira 'alternativa' de fazer isso. Está chegando o tempo em que tudo será necessário. Os outros métodos são hacks.

Peter Mortensen
fonte