2009-12-15 15 views
24

Utilizamos ajaxError global de jQuery() controlador para alertar al usuario de cualquier fallo AJAX:jQuery ajaxError() incendios manipulador si el usuario abandona la página antes de la página termina de cargar

$(document).ajaxError(function() { 
    $("There was a network or server error. Please try again later.").dialog({ 
     title: "Error", 
     modal: true, 
     resizable: false, 
     buttons: { 'Ok': function() { (this).dialog("close"); } } 
    }); 
}); 

Por desgracia, este controlador de errores global también dispara si el usuario abandona la página antes de que termine de cargarse. Estos son los pasos para reproducir el error:

  1. Visitas de usuario Página A, que incluye elementos que se cargan a través de AJAX.
  2. Elementos AJAX en la página A comienzan a cargar.
  3. El usuario hace clic en el enlace para visitar la página B antes de Los elementos AJAX en la página A se han terminado de cargar.
  4. Aparece el cuadro de diálogo de error brevemente antes de que el navegador redirige a la página B.

alguna idea de cómo podemos conseguir ajaxError() que se pueda iniciar cuando el error es causado directamente por el usuario que visita una página nueva?

ACTUALIZACIÓN: Aquí está mi código ahora, después de la incorporación de las sugerencias en los comentarios:

// I added a 3 second delay to our error dialog, enough time 
// for the user to leave for a new page: 
$(document).ajaxError(function() { 
    setTimeout(my_error_handler, 3000); 
}); 

// Warn user before leaving page if AJAX is still loading. 
// Not sure I'll keep this: 
$(document).ajaxStart(function() { 
    ajaxing = true; 
}); 

$(document).ajaxStop(function() { 
    ajaxing = false; 
}); 

window.onbeforeunload = function() { 
    if (typeof(ajaxing) != 'undefined' && ajaxing) { 
     return "Page elements are still loading!"; 
    } 
}; 

Respuesta

15

Bueno, sí, si el usuario navega a otra página, la xhr abortará, que es, en efecto, un éxito comunicación. Una solución sería registrar un oyente para el evento onbeforeunload, y desvincular ajaxError allí, básicamente diciendo: el usuario está a punto de abandonar la página, por lo que no deseo que se le informe sobre los errores ajax que podrían producirse.

Algunos sitios, como GMail, hacen al revés: si intenta navegar fuera de la página mientras todavía hay algunas solicitudes ajax pendientes, le da un mensaje que dice que todavía tiene algunos procesos ejecutándose, y permite al usuario decidir si permanecerá en el sitio hasta que la solicitud haya finalizado, o continuar y navegar.

+2

¡El enfoque de GMail es mucho mejor! – TheVillageIdiot

+2

bueno, sí, si debe tener un enfoque general general, supongo que eso es lo que prefiero también. aunque me gustaría mucho más si se pasara una bandera a la función que realizaba la llamada ajax, determinando si la solicitud actual era crítica o no. es decir, si la solicitud es solo una sesión para mantener viva, o una verificación de mensajes nuevos, o algo así, es posible que desee dejar que se cancele de manera silenciosa. –

+0

David, gracias por la sugerencia. Todavía no he probado qué navegadores son compatibles antes de la descarga, pero hasta ahora funciona bien en FF 3.5. También agregué un retraso de 3 segundos al cuadro de diálogo de error (una sugerencia de un comentario anterior que parece borrado ahora.) – richardkmiller

10

Sobre la base de la respuesta de David Hedlund por encima de aquí es el código que funciona para mí:

//enable global ajax error handling 
$(document).ajaxError(function (event, request, settings) { 
    //your error handling code here 
}); 

//user leaving page so ignore any unfinished ajax loads 
$(window).bind('beforeunload', function() { 
    $(document).unbind('ajaxError'); 
}); 

me dieron el 'ajaxError' especificaciones de la sección de comentarios de jquery ajaxError documentation. Tuve que vincular beforeunload a $(window) para admitir Chrome (IE funcionaba bien con el documento). .ajaxError no se activó cuando estaba vinculando al $(window), así que esta es la razón por la que tengo esta solución de ventana/documento.

Cuestiones relacionadas