2009-03-31 15 views
40

me disculpo si esto es algo que debería poder buscar. todos los términos que quería estaban demasiado sobrecargados ...maneja el error ajax cuando un usuario hace clic en actualizar

aquí está mi problema: cuando abro una página, se activa una serie completa de llamadas ajax. si presiono Shift + Refresh, todas esas llamadas ajax se consideran errores y muestran sus diálogos de mensaje de error antes de que la página entera se recargue por sí sola.

por lo que el error está siendo desencadenado por el cliente - ¿de todos modos puedo averiguar si este es el caso, así que puedo ignorarlo? por ejemplo, en el xmlhttprequest, o en la función ajax (estoy usando jQuery por cierto)

+0

Usted está poniendo el código dentro de una función annonymous jQuery onLoad ¿verdad? Al igual que, al comienzo de tu código tienes: $ (función() {/ * haz todas tus llamadas ajax aquí * /}); Debería esperar hasta que su DOM esté cargado antes de hacer llamadas ajax. – KyleFarris

Respuesta

19

[esto es una edición de la respuesta anterior, que había cuestiones pendientes que tengo ya resuelta]

jQuery lanza el evento de error cuando el usuario navega fuera de la página refrescándose, haciendo clic en un enlace o cambiando la URL en el navegador. Puede detectar este tipo de errores mediante la implementación de un controlador de errores para la llamada ajax, e inspeccionar el objeto XMLHttpRequest:

$.ajax({ 
    /* ajax options omitted */ 
    error: function (xmlHttpRequest, textStatus, errorThrown) { 
     if(xmlHttpRequest.readyState == 0 || xmlHttpRequest.status == 0) 
       return; // it's not really an error 
     else 
       // Do normal error handling 
}); 
+11

Esto no parece funcionar como se anuncia. Cuando introduzco un "error real" al deshabilitar mi conexión de red durante una encuesta larga, también veo readyState == 0 y status == 0. –

+6

Esto no funciona. Este método también deja de detectar errores reales – Sachindra

+9

Al reiniciar el servidor web en medio de una encuesta larga también se obtiene 'readyState == 0 && status == 0'. Este método no es confiable. –

6
var isPageBeingRefreshed = false; 

window.onbeforeunload = function() { 
    isPageBeingRefreshed = true; 
}; 

$.ajax({ 
    error: function (xhr, type, errorThrown) { 
     if (!xhr.getAllResponseHeaders()) { 
      xhr.abort(); 
      if (isPageBeingRefreshed) { 
       return; // not an error 
      } 
     } 
    } 
}); 
+2

Esto * casi * funcionó para mí. Funcionó en Firefox, Chrome, IE8, IE10 y en el navegador de existencias de Android. [Pero ** no ** en iOS Safari] (http://stackoverflow.com/questions/4127621/is-there-any-way-to-use-window-onbeforeunload-on-mobile-safari-for-ios- dispositivos). Una sugerencia de mejora (que aún no funciona en Safari/iOS) sería usar '$ (ventana) .on ('beforeunload', function() {...})' en lugar de 'window.beforeunload = function () {...} 'para no secuestrar/robar el controlador de acceso anticipado. Todavía estoy buscando algo que también funcione en iOS Safari. –

2

Las técnicas anteriores no funciona para una página periódicamente refrescante (por ejemplo, cada media segundos). He descubierto que el error causado por la actualización de la página se puede evitar mediante el retraso del proceso de manejo de errores por un período de tiempo reducido.

Ejemplo:

$.ajax(...) 
.success(...) 
.error(function(jqXHR) { 
setTimeout(function() { 
    // error showing process 
}, 1000); 
}); 

Además de eso

window.onbeforeunload = function() {// llamadas parada ajax}

evento se puede utilizar para menos frecuencia refrescantes llamadas ajax.

35

Existen varios enfoques sugeridos para la detección de este:

  • Varios han sugerido el uso de un controlador de beforeunload a establecer un indicador booleano para que el gestor de errores puede saber que la página está siendo descargada (véase la lista de publicaciones relacionadas/duplicadas a continuación). Esto es genial, excepto que mobile Safari on iOS doesn't support the beforeunload event.

  • Sachindra suggested un enfoque donde en lugar de disparar la función de error inmediatamente, se retrasó un segundo en un setTimeout(..., 1000). De esta forma, hay una buena posibilidad de que la página haya desaparecido para cuando se llame al manejador de errores. "Buena oportunidad" que es. Apuesto a que si tengo una gran página con, por ejemplo, muchos <input> s, podría tardar más de 1 segundo en descargarse, y quizás el controlador de errores se activaría de todos modos.

Por tanto, propongo una combinación de reliably detecting beforeunload support y si no se admite beforeunload (tos iPad/iPhone tos) volver a la demora del truco Sachindra.

Vea la solución completa con beforeunload detección y todo en este jsfiddle.

Parece que la situación es a little better for jQuery 2.x than for 1.x, pero 2.x también parece un poco flakey, por lo que esta sugerencia me parece prudente.

P.S: También hubo sugerencias que implican probar algunos campos en el objeto XHR/jqXHR. (Here y here). No he encontrado una combinación que pueda distinguir entre la navegación del usuario y el reinicio del servidor web durante una llamada AJAX de larga ejecución, y por lo tanto, no he encontrado este método útil para mí.

Esto es realmente también una respuesta a estas preguntas desbordamiento de pila relacionados/duplicados:

y estos puestos fuera de la pila Desbordamiento:

+0

En abril de 2017, este problema ahora solo ocurre en Firefox, que admite la descarga previa. –

2

versión combinada de nisanth074 y Peter V. Mørch respuestas, que trabajó para mí.

Ejemplo:

var isPageBeingRefreshed = false; 

$(window).on('beforeunload', function(){ 

    isPageBeingRefreshed = true; 
}); 

$.ajax({ 

    // Standart AJAX settings 

}).error(function(){ 

    if (!isPageBeingRefreshed) { 

     // Displaying error message 
    } 
}); 
Cuestiones relacionadas