javascript - Detectar se a conexão com a internet está offline?
Como posso detectar se a conexão com a internet está offline em JavaScript?
Resposta #1
Quase todos os principais navegadores agora suportam a propriedade window.navigator.onLine e os eventos de janela correspondentes online e offline. Execute o seguinte trecho de código para testá-lo:
console.log('Initially ' + (window.navigator.onLine ? 'on' : 'off') + 'line');
window.addEventListener('online', () => console.log('Became online'));
window.addEventListener('offline', () => console.log('Became offline'));
document.getElementById('statusCheck').addEventListener('click', () => console.log('window.navigator.onLine is ' + window.navigator.onLine));<button id="statusCheck">Click to check the <tt>window.navigator.onLine</tt> property</button><br /><br />
Check the console below for results:Tente configurar seu sistema ou navegador no modo offline/online e verifique o registro ou a propriedade window.navigator.onLine para as mudanças de valor.
Observe, no entanto, esta citação da Documentação da Mozilla:
No Chrome e Safari, se o navegador não conseguir se conectar a uma rede local (LAN) ou a um roteador, ele está offline; todas as outras condições retornam
true. Portanto, enquanto você pode assumir que o navegador está offline quando ele retorna um valorfalse, você não pode assumir que um valortruenecessariamente significa que o navegador pode acessar a internet. Você pode estar recebendo falsos positivos, como em casos em que o computador está executando um software de virtualização que possui adaptadores de Ethernet virtuais que estão sempre "conectados". Portanto, se você realmente deseja determinar o status online do navegador, deve desenvolver meios adicionais para verificar.No Firefox e no Internet Explorer, mudar o navegador para o modo offline envia um valor
false. Até o Firefox 41, todas as outras condições retornam um valortrue; desde o Firefox 41, no OS X e no Windows, o valor seguirá a conectividade real da rede.
(ênfase é minha)
Isso significa que se window.navigator.onLine for false (ou você receber um evento offline), você tem a garantia de não ter conexão com a Internet.
Se for true, no entanto (ou se você receber um evento online), isso apenas significa que o sistema está conectado a alguma rede, na melhor das hipóteses. Isso não significa, por exemplo, que você tem acesso à Internet. Para verificar isso, você ainda precisará usar uma das soluções descritas nas outras respostas.
Inicialmente, eu pretendia postar isso como uma atualização para a resposta de Grant Wagner, mas pareceu uma edição demais, especialmente considerando que a atualização de 2014 já não era dele.
Resposta #2
Você pode determinar que a conexão foi perdida fazendo solicitações XHR falhadas.
A abordagem padrão é tentar a solicitação novamente algumas vezes. Se não for concluída, avise o usuário para verificar a conexão e falhe de forma elegante.
Observação: Colocar o aplicativo inteiro em um estado "offline" pode levar a muito trabalho suscetível a erros ao gerenciar o estado... conexões sem fio podem aparecer e desaparecer, etc. Portanto, sua melhor opção pode ser simplesmente falhar de forma elegante, preservar os dados e alertar o usuário... permitindo que ele eventualmente resolva o problema de conexão, se houver, e continue usando seu aplicativo com uma boa quantidade de tolerância.
Observação: Você poderia verificar um site confiável como o Google para conectividade, mas isso pode não ser totalmente útil apenas tentando fazer sua própria solicitação, porque enquanto o Google pode estar disponível, sua própria aplicação pode não estar, e você ainda terá que lidar com seu próprio problema de conexão. Tentar enviar um ping para o Google seria uma boa forma de confirmar se a própria conexão com a internet está fora do ar, então, se essa informação for útil para você, pode valer a pena o esforço.
Observação: Enviar um Ping poderia ser feito da mesma maneira que você faria qualquer tipo de requisição Ajax bidirecional, mas enviar um ping para o Google, neste caso, apresentaria alguns desafios. Primeiro, teríamos os mesmos problemas de domínio cruzado que normalmente são encontrados ao fazer comunicações Ajax. Uma opção é configurar um proxy no lado do servidor, onde realmente pingaríamos o Google (ou qualquer outro site), e retornaríamos os resultados do ping para o aplicativo. Isso é um catch-22 porque se a conexão com a 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 conseguiremos perceber a diferença. Outras técnicas de domínio cruzado poderiam ser tentadas, por exemplo, incorporando um iframe em sua página que aponte para google.com, e então verificando periodicamente o iframe para sucesso/falha (examinando o conteúdo, etc). Incorporar uma imagem pode realmente 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. Então, novamente, determinar o estado da conexão com a internet como um todo pode ser mais problemático do que vale a pena. Você terá que avaliar essas opções para seu aplicativo específico.
Resposta #3
O IE 8 suportará a propriedade window.navigator.onLine.
Mas é claro que isso não ajuda com outros navegadores ou sistemas operacionais. Prevejo que outros fornecedores de navegadores decidirão fornecer essa propriedade também, dada a importância de saber o status online/offline em aplicativos Ajax.
Até que isso aconteça, tanto XHR quanto um Image() ou uma requisição <img> podem fornecer algo próximo da funcionalidade que você deseja.
Atualização (16/11/2014)
Os principais navegadores agora suportam esta propriedade, mas seus resultados podem variar.
Citação da Documentação da Mozilla:
No Chrome e no Safari, se o navegador não consegue se conectar a uma rede local (LAN) ou a um roteador, ele está offline; todas as outras condições retornam
true. Portanto, embora você possa assumir que o navegador está offline quando ele retorna um valorfalse, você não pode assumir que um valor verdadeiro necessariamente significa que o navegador pode acessar a internet. Você pode estar recebendo falsos positivos, como em casos onde 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, você deve desenvolver meios adicionais de verificação.No Firefox e no Internet Explorer, alternar o navegador para o modo offline envia um valor
false. Todas as outras condições retornam um valortrue.
Resposta #4
if (navigator.onLine) {
alert('online');
} else {
alert('offline');
}
Veja onLine Uso básico
Resposta #5
Há várias maneiras de fazer isso:
- Requisição AJAX para o seu próprio site. Se essa requisição falhar, há uma boa chance de que a conexão seja a culpada. A documentação do JQuery possui uma seção sobre como lidar com requisições AJAX falhas. Cuidado com a Política de Mesma Origem ao fazer isso, que pode impedir você de acessar sites fora do seu domínio.
- Você poderia colocar um
onerrorem umimg, como<img src="http://www.example.com/singlepixel.gif" onerror="alert('Conexão perdida');" />.
Este método também pode falhar se a imagem de origem for movida/renomeada, e geralmente seria uma escolha inferior à opção ajax.
Então, existem várias maneiras diferentes de tentar detectar isso, nenhuma perfeita, mas na ausência da capacidade de sair do sandbox do navegador e acessar diretamente o status da conexão de rede do usuário, elas parecem ser as melhores opções.
Resposta #6
Como disse olliej, usar a propriedade do navegador navigator.onLine é preferível a enviar solicitações de rede e, de acordo com developer.mozilla.org/En/Online_and_offline_events, é até suportado por versões antigas do Firefox e do IE.
Recentemente, o WHATWG especificou a adição dos eventos online e offline, caso você precise reagir às mudanças em navigator.onLine.
Por favor, também preste atenção ao link postado por Daniel Silveira, que aponta que confiar nesses sinais/propriedades para sincronizar com o servidor nem sempre é uma boa ideia.
Resposta #7
window.navigator.onLine
é o que você está procurando, mas algumas coisas aqui para adicionar, primeiro, se for algo no seu aplicativo que você queira continuar verificando (como para ver se o usuário de repente fica offline, o que geralmente está correto na maioria das vezes, então você também precisa ouvir mudanças), para isso você adiciona um listener de evento à janela para detectar qualquer mudança, para verificar se o usuário fica offline, você pode fazer:
window.addEventListener("offline",
()=> console.log("No Internet")
);
e para verificar se está online:
window.addEventListener("online",
()=> console.log("Connected Internet")
);
Resposta #8
Você pode usar o callback error do $.ajax(), que é acionado se a requisição falhar. Se textStatus for igual à string "timeout", provavelmente significa que a conexão foi 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 requisição falhar. A função recebe três argumentos: o objeto XMLHttpRequest, uma string descrevendo o tipo de erro que ocorreu e um objeto de exceção opcional, se houver ocorrido algum. Valores possíveis para o segundo argumento (além de null) são "timeout", "error", "notmodified" e "parsererror". Este é um Evento 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!');
}
}
});
Resposta #9
A API de Cache de Aplicações do HTML5 especifica navigator.onLine, que atualmente está disponível nas betas do IE8, nas versões noturnas do WebKit (por exemplo, Safari), e já é suportada no Firefox 3
Resposta #10
Eu sei que esta pergunta já foi respondida, mas eu gostaria de adicionar meus 10 centavos explicando o que é melhor e o que não é.
Window.navigator.onLine
Percebi que algumas respostas falaram sobre essa opção, mas nunca mencionaram nada a respeito da ressalva.
Esta opção envolve o uso de "window.navigator.onLine", que é uma propriedade da Interface do Navegador disponível na maioria dos navegadores modernos. Na verdade, não é uma opção viável para verificar a disponibilidade da internet porque, primeiro, é centrada no navegador e, segundo, a maioria dos navegadores implementa essa propriedade de forma diferente.
No Firefox: A propriedade retorna um valor booleano, com
truesignificando online efalsesignificando offline, mas a ressalva aqui é que "o valor só é atualizado quando o usuário segue links ou quando um script solicita uma página remota." Portanto, se o usuário ficar offline e você consultar a propriedade a partir de uma função ou script em JS, a propriedade sempre retornarátrueaté que o usuário siga um link.No Chrome e Safari: Se o navegador não conseguir se conectar a uma rede local (LAN) ou a um roteador, ele está offline; todas as outras condições retornam verdadeiro. Portanto, embora você possa assumir que o navegador está offline quando ele retorna um valor falso, você não pode assumir que um valor verdadeiro necessariamente significa que o navegador pode acessar a internet. Você pode obter falsos positivos, como em casos onde o computador está rodando um software de virtualização que possui adaptadores de ethernet virtuais que estão sempre "conectados".
As declarações acima estão simplesmente tentando informar que apenas os navegadores não conseguem identificar. Então, basicamente, esta opção é pouco confiável.
Enviando solicitação ao recurso do próprio servidor
- Nenhuma disponibilidade de servidor é 100% confiável, portanto, se por algum motivo o seu servidor não estiver acessível, seria assumido erroneamente que o usuário está offline, enquanto ele está conectado à internet.
- Múltiplas requisições para o mesmo recurso podem retornar uma resposta em cache, tornando o resultado da resposta HTTP não confiável.
Se você concorda que seu servidor está sempre online, então você pode escolher esta opção.
Aqui está um pequeno trecho para buscar seu próprio recurso:
// This fetches your website's favicon, so replace path with favicon url
// Notice the appended date param which helps prevent browser caching.
fetch('/favicon.ico?d='+Date.now())
.then(response => {
if (!response.ok)
throw new Error('Network response was not ok');
// At this point we can safely assume the user has connection to the internet
console.log("Internet connection available");
})
.catch(error => {
// The resource could not be reached
console.log("No Internet connection", error);
});
Enviando Solicitação para Recurso de Servidor de Terceiros
Esta opção envolve fazer uma requisição HTTP para um recurso de servidor externo e, se acessível, assumir a disponibilidade da internet; caso contrário, o usuário está offline. A principal ressalva disso é o compartilhamento de recursos entre origens (CORS), que atua como uma limitação. A maioria dos sites respeitáveis bloqueia requisições CORS, mas para alguns você pode conseguir o que deseja.
Abaixo um trecho simples para buscar recurso externo, igual ao acima, mas com URL de recurso externo:
// Firstly you trigger a resource available from a reputable site
// For demo purpose you can use the favicon from MSN website
// Also notice the appended date param which helps skip browser caching.
fetch('https://static-global-s-msn-com.akamaized.net/hp-neu/sc/2b/a5ea21.ico?d='+Date.now())
.then(response => {
// Check if the response is successful
if (!response.ok)
throw new Error('Network response was not ok');
// At this point we can safely say the user has connection to the internet
console.log("Internet available");
})
.catch(error => {
// The resource could not be reached
console.log("No Internet connection", error);
});
Então, finalmente, para o meu projeto pessoal, eu optei pela segunda opção, que envolve solicitar recursos do próprio servidor, porque basicamente há muitos fatores para determinar se há "Conexão com a Internet" no dispositivo de um usuário, não apenas a partir do contêiner do seu site ou de uma API limitada do navegador.
Lembre-se de que seus usuários também podem estar em um ambiente onde alguns sites ou recursos estão bloqueados, proibidos e inacessíveis, o que por sua vez afeta a lógica de verificação de conectividade. A melhor opção será:
- Tente acessar um recurso em seu próprio servidor porque este é o ambiente dos seus usuários (Normalmente eu uso o favicon do site porque a resposta é muito leve e não é atualizado com frequência).
- Se não houver conexão com o recurso, simplesmente diga "Erro na conexão" ou "Conexão perdida" quando precisar notificar o usuário, em vez de assumir um amplo "Sem conexão com a internet", que depende de muitos fatores.
