2012-03-20 14 views
12

Estoy probando la aplicación fuera de línea HTML5. Para hacer eso, detendré mi servidor web local (IIS) y la aplicación abierta. Se carga bien, pero falló tan pronto como solicitó el método API del lado del servidor.HTML5/JS - compruebe que la aplicación está fuera de línea

Quiero evitar eso y en lugar de $ .get ('/ api/method') leer los datos de mi almacenamiento local. Pero puedo encontrar cualquier facilidad para entender que mi aplicación está fuera de línea.

if (/* online */) { 
    // fire ajax 
} else { 
    // ask localstorage 
} 

He intentado utilizar navigation.onLine pero parece ser siempre verdad (al menos puedo ver que en Chrome).

¿Tiene alguna sugerencia?

EDIT: teniendo en cuenta las respuestas actuales. La aplicación entiende claramente que está fuera de línea, ya que toma recursos de acuerdo con cache.manifest. Es ridículo para mí, ese cliente necesita hacer cualquier tipo de trucos y pings. Supongo que debería haber una manera fácil de verificar el modo actual.

+0

intento mirar upshot.js fuentes. han implementado este comportamiento – mironych

+2

No hay una manera fácil de verificar porque no hay una manera fácil de saber qué constituye 'en línea'. La interfaz de red podría estar activa, el dispositivo/PC podría estar en una red, pero si esa red no tiene conexión a Internet, ¿está conectado o desconectado? Eso dependería de si la aplicación está en Internet o en la intranet. ¿Qué sucede si tiene acceso a Internet pero su aplicación está bloqueada por las reglas del firewall, su aplicación está en línea o fuera de línea? La forma más fácil de verificar * es * algún tipo de ping. – robertc

+0

@robertc su comentario tiene mucho sentido para mí, ¡gracias! –

Respuesta

13

Una forma fácil de comprobar es añadir una sección de respaldo en su manifiesto de la siguiente manera:

FALLBACK 
/online.js /offline.js 

Luego, en online.js se establece una variable global a la verdad, en offline.js lo establece en falso y solo solicita online.js de Ajax cada vez que planea hacer alguna conexión de red y hacer cualquier procesamiento que necesite condicionalmente en la devolución de llamada. Mientras tanto, mantén todo el lado del cliente de tus datos de aplicaciones.

Un enfoque alternativo es a blocking polyfill for navigator.onLine as suggested by Remy Sharp.

+0

¡Parece una solución bastante sólida! –

+0

funciona como el encanto! –

0

¿Qué tal si hacemos un manejo de errores? Como un ciclo Try Catch.

try { 
    //Run some code here 
    } 
catch(err) { 
    //Handle errors here 
    } 
+0

hmm, ¿qué código propones ejecutar allí? –

+1

haga algo así como navegar a Google.com, luego configure un booleano como verdadero si funciona o falso si no lo hace. Hay una posibilidad muy alta de que Google no disminuya ... nunca. Por lo tanto, tiene más posibilidades de probar realmente si la aplicación está en línea, y no solo de que el recurso web al que está intentando acceder está fuera de línea. –

+1

Disponibilidad de Google y modo fuera de línea para mi aplicación: es una gran diferencia. Como dije en mi pregunta, simplemente detuve mi servicio web local ... No estoy 'deteniendo' el internet. –

3

estado en línea podría ser también la inspección de hacer una petición ajax HEAD con un tiempo de espera y cuando se alcanza el tiempo de espera (o la llamada devuelve un estado de error) se puede asumir que está trabajando fuera de línea (no hay capabitlities de red) y tiene que usar localstorage en su lugar

De hecho, en aras de la coherencia del estado, el almacenamiento local debe usarse como respaldo no solo cuando no está conectado, sino también cuando está en línea y el recurso específico Ajax no está disponible temporalmente (por ejemplo, sobrecarga del sitio). Por supuesto, tendrá que realizar un sondeo continuo a ese recurso con un tiempo de espera regular (o incremental) hasta que vuelva a estar disponible.

0

¿Es una opción preguntarle a localstorage cuando la llamada ajax falla con un error específico (tiempo de espera de la operación)?

O como la página (al menos parcialmente) se genera con secuencias de comandos del servidor, puede incluir una marca de tiempo de solicitud (o identificación única) en su página con script del lado del servidor y colocarla en localstorage. Luego puede ver si la página se carga desde la caché al verificar la identificación almacenada contra la que se procesó.

0

La mejor opción podría ser utilizar el evento error de la función jQuery $.get() para consultar localStorage en lugar de su servidor web. Esto tiene el beneficio de retroceder si su servidor se vuelve inalcanzable y si los usuarios no pueden acceder a Internet.

$.get({ 
    success: //deal with postback from ajax call, 
    error: //Whoops no access to server deal with it in a local way 
}) 
1

que estaba necesitando la misma funcionalidad y después de mucho buscar encontró esta función:

http://louisremi.com/2011/04/22/navigator-online-alternative-serverreachable/

Aquí está el código del artículo, en caso de que el enlace se cae:

function serverReachable() { 
    // IE vs. standard XHR creation 
    var x = new (window.ActiveXObject || XMLHttpRequest)("Microsoft.XMLHTTP"), 
    s; 
    x.open(
     // requesting the headers is faster, and just enough 
     "HEAD", 
     // append a random string to the current hostname, 
     // to make sure we're not hitting the cache 
     window.location.href.split("?")[0] + "?" + Math.random(), 
     // make a synchronous request 
     false 
); 
    try { 
     x.send(); 
     s = x.status; 
     // Make sure the server is reachable 
     return (s >= 200 && s < 300 || s === 304); 
    } 
    // catch network & other problems 
    catch (e) { 
    return false; 
    } 
} 

Tenga en cuenta que el código anterior incluye una solución de Scott Jehl para trabajar con localhost que se publica más abajo en los comentarios. Y aquí hay un enlace a una versión de jQuery de la misma función:

https://gist.github.com/scottjehl/947084

y el código de ese enlace:

function serverReachable() { 
    var s = $.ajax({ 
      type: "HEAD", 
      url: window.location.href.split("?")[0] + "?" + Math.random(), 
      async: false 
     }).status; 
    return s >= 200 && s < 300 || s === 304; 
}; 

He encontrado que esta técnica sea realmente eficaz. Debido a que la solicitud es solo para la información del encabezado, es razonablemente rápida y funciona en todos los navegadores. ¡Gran éxito! :)

espero a otros a encontrar esta tan útil como lo hice. :)

Cuestiones relacionadas