¿Cómo detectar que la conexión a Internet está fuera de línea en JavaScript?
¿Cómo detectar que la conexión a Internet está fuera de línea en JavaScript?
Respuestas:
Puede determinar que la conexión se pierde haciendo solicitudes XHR fallidas .
El enfoque estándar es volver a intentar la solicitud varias veces. Si no pasa, alerta al usuario para que verifique la conexión y falla con gracia .
Nota al margen: Poner toda la aplicación en un estado "fuera de línea" puede llevar a una gran cantidad de trabajo de manejo de estado propenso a errores ... las conexiones inalámbricas pueden ir y venir, etc. Así que su mejor opción puede ser simplemente fallar con gracia, preservar el datos y alertar al usuario .. permitiéndole eventualmente solucionar el problema de conexión si existe, y continuar usando su aplicación con una buena cantidad de perdón.
Nota al margen: puede verificar la conectividad de un sitio confiable como google, pero esto puede no ser del todo útil simplemente tratando de hacer su propia solicitud, porque si bien Google puede estar disponible, su propia aplicación puede no estarlo, y usted todavía va a tiene que manejar su propio problema de conexión. Intentar enviar un ping a Google sería una buena manera de confirmar que la conexión a Internet en sí misma no funciona, por lo que si esa información es útil para usted, entonces podría valer la pena.
Nota al margen : el envío de un Ping se podría lograr de la misma manera que haría cualquier tipo de solicitud ajax bidireccional, pero enviar un ping a google, en este caso, plantearía algunos desafíos. Primero, tendríamos los mismos problemas de dominio cruzado que normalmente se encuentran al hacer comunicaciones Ajax. Una opción es configurar un proxy del lado del servidor, en el que en realidad buscamos en ping
Google (o en cualquier sitio), y devolvemos los resultados del ping a la aplicación. Esta es una trampa-22porque si la conexión a Internet es realmente el problema, no podremos acceder al servidor, y si el problema de conexión es solo en nuestro propio dominio, no podremos notar la diferencia. Se podrían probar otras técnicas de dominio cruzado, por ejemplo, incrustando un iframe en su página que apunte a google.com, y luego sondeando el iframe por éxito / fracaso (examine el contenido, etc.). Incrustar una imagen puede no decirnos nada realmente, porque necesitamos una respuesta útil del mecanismo de comunicación para sacar una buena conclusión sobre lo que está sucediendo. De nuevo, determinar el estado de la conexión a Internet en su conjunto puede ser más problemático de lo que vale. Tendrá que sopesar estas opciones para su aplicación específica.
IE 8 admitirá la propiedad window.navigator.onLine .
Pero, por supuesto, eso no ayuda con otros navegadores o sistemas operativos. Predigo que otros proveedores de navegadores decidirán proporcionar esa propiedad también dada la importancia de conocer el estado en línea / fuera de línea en las aplicaciones Ajax.
Hasta que eso ocurra, ya sea XHR o un Image()
o <img>
solicitud pueden proporcionar algo cercano a la funcionalidad que desea.
Actualización (2014/11/16)
Los principales navegadores ahora admiten esta propiedad, pero sus resultados variarán.
Cita de la documentación de Mozilla :
En Chrome y Safari, si el navegador no puede conectarse a una red de área local (LAN) o un enrutador, está desconectado; Todas las demás condiciones vuelven
true
. Entonces, si bien puede suponer que el navegador está fuera de línea cuando devuelve unfalse
valor, no puede suponer que un valor verdadero necesariamente significa que el navegador puede acceder a Internet. Podría estar obteniendo falsos positivos, como en los casos en que la computadora ejecuta un software de virtualización que tiene adaptadores virtuales de Ethernet que siempre están "conectados". Por lo tanto, si realmente desea determinar el estado en línea del navegador, debe desarrollar medios adicionales para verificar.En Firefox e Internet Explorer, cambiar el navegador al modo fuera de línea envía un
false
valor. Todas las demás condiciones devuelven untrue
valor.
Casi todos los principales navegadores ahora admiten la window.navigator.onLine
propiedad y los eventos correspondientes online
y de offline
ventana:
window.addEventListener('online', () => console.log('came online'));
window.addEventListener('offline', () => console.log('came offline'));
Intente configurar su sistema o navegador en modo fuera de línea / en línea y verifique la consola o la window.navigator.onLine
propiedad para ver los cambios de valor. También puede probarlo en este sitio web .
Sin embargo, tenga en cuenta esta cita de la documentación de Mozilla :
En Chrome y Safari, si el navegador no puede conectarse a una red de área local (LAN) o un enrutador, está desconectado; Todas las demás condiciones vuelven
true
. Entonces, si bien puede suponer que el navegador está fuera de línea cuando devuelve unfalse
valor , no puede suponer que untrue
valor necesariamente significa que el navegador puede acceder a Internet . Podría estar recibiendo falsos positivos, como en los casos en que la computadora ejecuta un software de virtualización que tiene adaptadores virtuales de Ethernet que siempre están "conectados". Por lo tanto, si realmente desea determinar el estado en línea del navegador, debe desarrollar medios adicionales para verificar.En Firefox e Internet Explorer, cambiar el navegador al modo fuera de línea envía un
false
valor. Hasta Firefox 41, todas las demás condiciones devuelven untrue
valor; desde Firefox 41, en OS X y Windows, el valor seguirá la conectividad de red real.
(el énfasis es mío)
Esto significa que si window.navigator.onLine
es así false
(o si obtiene un offline
evento), se garantiza que no tendrá conexión a Internet.
true
Sin embargo, si es así (o si obtiene un online
evento), solo significa que el sistema está conectado a alguna red, en el mejor de los casos. No significa que tenga acceso a Internet, por ejemplo. Para verificar eso, aún necesitará usar una de las soluciones descritas en las otras respuestas.
Inicialmente tenía la intención de publicar esto como una actualización de la respuesta de Grant Wagner , pero parecía demasiado editado, especialmente teniendo en cuenta que la actualización de 2014 ya no era de él .
Hay muchas maneras de hacer esto:
Podrías poner onerror
un img
, como
<img src='http://www.example.com/singlepixel.gif'
onerror='alert("Connection dead");' />
Este método también podría fallar si la imagen de origen se mueve / cambia de nombre, y generalmente sería una opción inferior a la opción ajax.
Por lo tanto, hay varias formas diferentes de intentar detectar esto, ninguna perfecta, pero en ausencia de la capacidad de saltar del entorno limitado del navegador y acceder directamente al estado de conexión de red del usuario, parecen ser las mejores opciones.
if(navigator.onLine){
alert('online');
} else {
alert('offline');
}
Puede usar la devolución de llamada de $ .ajax ()error
, que se activa si la solicitud falla. Si textStatus
es igual a la cadena "tiempo de espera", probablemente significa que la conexión está interrumpida:
function (XMLHttpRequest, textStatus, errorThrown) {
// typically only one of textStatus or errorThrown
// will have info
this; // the options for this ajax request
}
Del documento :
Error : se llamará a una función si la solicitud falla. A la función se le pasan tres argumentos: el objeto XMLHttpRequest, una cadena que describe el tipo de error que se produjo y un objeto de excepción opcional, si se produjo uno. Los valores posibles para el segundo argumento (además de nulo) son "timeout", "error", "notmodified" y "parsererror". Este es un evento Ajax
Así por ejemplo:
$.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 dijo olliej, navigator.onLine
es preferible usar la propiedad del navegador que enviar solicitudes de red y, en consecuencia, con developer.mozilla.org/En/Online_and_offline_events , incluso es compatible con versiones antiguas de Firefox e IE.
Recientemente, el WHATWG ha especificado la adición de los eventos online
y offline
, en caso de que necesite reaccionar antenavigator.onLine
cambios.
También preste atención al enlace publicado por Daniel Silveira que señala que confiar en esas señales / propiedades para sincronizar con el servidor no siempre es una buena idea.
window.navigator.onLine
es lo que está buscando, pero aquí hay algunas cosas que agregar, primero, si es algo en su aplicación que desea seguir verificando (como ver si el usuario se desconecta repentinamente, lo cual es correcto en este caso la mayor parte del tiempo, luego usted necesita escuchar el cambio también), para eso agrega un escucha de eventos a la ventana para detectar cualquier cambio, para verificar si el usuario se desconecta, puede hacer:
window.addEventListener("offline",
()=> console.log("No Internet")
);
y para verificar si está en línea:
window.addEventListener("online",
()=> console.log("Connected Internet")
);
onLine
. Los navegadores definen el estado de estar en línea de manera muy diferente. Echa un vistazo a developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine .
Tuve que hacer una aplicación web (basada en ajax) para un cliente que trabaja mucho con las escuelas, estas escuelas a menudo tienen una mala conexión a Internet. ¡Utilizo esta función simple para detectar si hay una conexión, funciona muy bien!
Yo uso CodeIgniter y 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();
}
});
}
Una llamada ajax a su dominio es la forma más fácil de detectar si está desconectado
$.ajax({
type: "HEAD",
url: document.location.pathname + "?param=" + new Date(),
error: function() { return false; },
success: function() { return true; }
});
esto es solo para darle el concepto, debería mejorarse.
Por ejemplo, error = 404 aún debería significar que estás en línea
Creo que es una forma muy 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;
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
Estaba buscando una solución del lado del cliente para detectar si Internet estaba caído o si mi servidor estaba caído. Las otras soluciones que encontré siempre parecían depender de un archivo o imagen de script de un tercero, lo que para mí no parecía resistir el paso del tiempo. Una imagen o script alojado externo podría cambiar en el futuro y provocar un error en el código de detección.
He encontrado una manera de detectarlo buscando un xhrStatus con un código 404. Además, uso JSONP para evitar la restricción CORS. Un código de estado que no sea 404 muestra que la conexión a Internet no funciona.
$.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)
}
}
});
Mi manera.
<!-- 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>
El problema de algunos métodos navigator.onLine
es que no son compatibles con algunos navegadores y versiones móviles, una opción que me ayudó mucho fue usar el XMLHttpRequest
método clásico y también prever el posible caso de que el archivo se almacenara en caché con respuestaXMLHttpRequest.status
mayor que 200 y menos de 304.
Aquí está mi 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 :(');
}
}
}
Hay dos respuestas para dos senarios diferentes:
Si está utilizando JavaScript en un sitio web (es decir, o en cualquier parte frontal) La forma más sencilla de hacerlo es:
<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>
Pero si está utilizando js en el lado del servidor (es decir, nodo, etc.), puede determinar que la conexión se pierde al realizar solicitudes XHR fallidas.
El enfoque estándar es volver a intentar la solicitud varias veces. Si no pasa, alerta al usuario para que verifique la conexión y falla con gracia.
cabeza de solicitud en error de solicitud
$.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");
}
});
}
});
Aquí hay un fragmento de una utilidad auxiliar que tengo. Este es JavaScript de espacio de nombres:
network: function() {
var state = navigator.onLine ? "online" : "offline";
return state;
}
Debería usar esto con la detección de métodos; de lo contrario, active una forma 'alternativa' de hacerlo. Se acerca rápidamente el momento en que esto será todo lo que se necesita. Los otros métodos son hacks.