Como detectar se a conexão com a Internet está offline em JavaScript?
Como detectar se a conexão com a Internet está offline em JavaScript?
Respostas:
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 ping
Google (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.
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 umfalse
valor, 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
false
valor. Todas as outras condições retornam umtrue
valor.
Quase todos os principais navegadores agora suportam a window.navigator.onLine
propriedade e os eventos correspondentes online
e offline
window:
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.onLine
propriedade 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 umfalse
valor , não será possível assumir que umtrue
valor 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
false
valor. Até o Firefox 41, todas as outras condições retornam umtrue
valor; 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.onLine
for false
(ou você receber um offline
evento), é garantido que você não tem conexão com a Internet.
true
No entanto, se for (ou você receber um online
evento), 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 .
Existem várias maneiras de fazer isso:
Você pode colocar onerror
um 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.
if(navigator.onLine){
alert('online');
} else {
alert('offline');
}
Você pode usar o retorno de chamada de $ .ajax ()error
, que é acionado se a solicitação falhar. Se for textStatus
igual à 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!');
}
}
});
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 online
e offline
, caso você precise reagir às navigator.onLine
alteraçõ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.
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")
);
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 .
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();
}
});
}
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
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;
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
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)
}
}
});
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>
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 XMLHttpRequest
método clássico e também prever o possível caso de o arquivo ser armazenado em cache com resposta XMLHttpRequest.status
maior 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 :(');
}
}
}
Existem 2 respostas para dois senarios diferentes: -
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>
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.
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");
}
});
}
});
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.