Comprobar la conexión a internet con JavaScript JavaScript
Al construir una aplicación web, rápidamente te verás en la necesidad de comprobar la conexión a internet. Por ejemplo, una PWA (Progressive Web Application), por definición, debe funcionar offline y comprobar la conectividad es una tarea de rutina.
Esto no significa necesariamente que se pueda acceder al contenido de forma offline, significa que la aplicación maneje la situación, no el navegador. En otras palabras, el mensaje de error por falta de conexión en el navegador se sustituye por un mensaje de error en la propia aplicación. En este contexto, se puede decir que la aplicación funciona offline, aunque no se pueda acceder al contenido. A partir de aquí, la aplicación puede implementar o no el almacenamiento de contenido para acceso offline.
navigator.onLine
navigator.onLine
es una propiedad de la interfaz Navigator (window.navigator
) de tipo lógico que devuelve true
si el navegador se encuentra conectado a la red y false
en caso contrario.
// Ver https://developer.mozilla.org/es/docs/Web/API/NavigatorOnLine/onLine
if(navigator.onLine) {
// el navegador está conectado a la red
} else {
// el navegador NO está conectado a la red
}
Además, podemos subscribirnos a los eventos window.offline
y window.online
. Podríamos, por ejemplo, añadir una clase al body
:
if(navigator.onLine) {
goOnline();
} else {
goOffile();
}
window.addEventListener('offline', goOffline());
window.addEventListener('online', goOnline());
function goOnline() {
document.body.classList.remove('offline');
document.body.classList.add('online');
// Hacer algo más al ir online
}
function goOffline() {
document.body.classList.remove('online');
document.body.classList.add('online');
// Hacer algo más al ir offline
}
Un pequeño detalle: online no es igual a Internet
Según la información que aparece en MDN, no todos los navegadores han implementado esta propiedad de la misma forma. En general, Chrome y Safari devuelven true
si el navegador se puede conectar a una red de área local (LAN) o a un router, lo cual no significa necesariamente que el navegador pueda acceder a Internet, ya que puede estar conectado a una intranet sin acceso a internet.
La solución a este problema es no asumir que hay acceso a internet si navigator.onLine
devuelve true
. Si devuelve false
es seguro que no hay acceso a Internet, pero no al contrario. Algunas bibliotecas, como Offline.js, hacen una solicitud a un archivo remoto para comprobar si hay acceso a Internet o no, y esta es una práctica bastante común y que funciona bien.
Pero el hecho de hacer una solicitud a Internet para comprobar si hay conexión no siempre es lo más aconsejable.
Por ejemplo, imagina hacer esta comprobación para decidir si hacer o no un fetch
o un ajax. Estaríamos añadiendo un retraso considerable. Si navigator.onLine
es false
si podríamos evitar el fetch
o el ajax
de forma segura ahorrando la espera hasta el timeout. Pero si es true
, tendríamos que seguir manejando los posibles timeouts y códigos de estado en las respuestas HTTP, por ejemplo:
// Sólo hacer el fetch si navigator.onLine es true
if( navitagor.onLine ) {
fetch('https://example.com/flowers.jpg')
.then(function(response) {
if(!response.ok) {
// Parece que hay acceso a Internet,
// pero la respuesta no ha sido ok
// También se puede comprobar el código de estado con response.status
// Y hacer algo específico según el estado exacto recibido
throw Error(response.statusText);
}
return response;
}).then(function(response) {
// response.ok fue true
console.log('ok');
resolve(response);
}).catch(function(error) {
console.log('Problema al realizar la solicitud: ' + error.message);
reject(error);
});
}