Abortar la solicitud ajax de JSONP con jQuery
callback (5)
Estoy usando una llamada ajax JSONP para cargar contenido de un dominio diferente, y todo esto se ejecuta si el usuario provoca un "mouseover" en un botón.
Puedo capturar el retorno de la llamada $ .ajax () como un objeto xhr, y usarlo para abortar la solicitud ajax cada vez que el usuario provoque un "mouseover". Pero a la función de devolución de llamada JSONP todavía se le llama, y esto causa un error, y creo que es porque el método xhr.abort () no impide que se llame a la función de devolución de llamada.
He intentado rodear la llamada $ .ajax () con try {} catch (e) {}, pero después de llamar al método xhr.abort (), el error continúa.
¿Hay alguna manera de manejar esa excepción?
La excepción planteada es así (según Firebug): jQuery16102234208755205157_1308941669256 no es una función
Y la estructura interna de la excepción es así: jQuery16102234208755205157_1308941669256 ({... mi json data de un dominio diferente ...})
En jQuery 1.5, todas las API de Ajax tienen un objeto envoltorio alrededor de los objetos XHR nativos. Echa un vistazo a:
http://api.jquery.com/jQuery.ajax/#jqXHR
jqxhr.abort(); // should be what you''re looking for
La respuesta básica es simplemente la que se proporciona here : realmente no puede abort()
una llamada JSONP. Entonces, la pregunta real es: ¿cómo evitar tanto las invocaciones de devolución de llamada superfluas como el error que está viendo?
No puede utilizar try...catch
alrededor de la devolución de llamada porque es asíncrono; tendrías que atraparlo desde el final de jQuery, y jQuery generalmente no maneja las excepciones generadas por devoluciones de llamada. (Discuto esto en mi libro, Async JavaScript .) Lo que quiere hacer en su lugar es usar un identificador único para cada llamada Ajax y, cuando se invoca la devolución de llamada exitosa, verifique si ese identificador es el mismo que cuando hizo la llamada. llamada. Aquí hay una implementación fácil:
var requestCount = 0;
$.ajax(url, {
dataType: ''jsonp'',
requestCount: ++requestCount,
success: function(response, code) {
if (requestCount !== this.requestCount) return;
// if we''re still here, this is the latest request...
}
});
Aquí estoy aprovechando el hecho de que cualquier cosa que pase a $.ajax
se adjunta al objeto que se usa como this
en la devolución de llamada.
Sería bueno si jQuery hizo abort()
hacer esto por nosotros, por supuesto.
La respuesta de Trevor Burnham es bastante buena, pero en lugar de rastrear un recuento de solicitudes, debe comparar la solicitud con el parámetro XHR, como tal;
doRequest: function() {
this._freeRequest();
this._request = $.getJSON(url + params + ''&callback=?'', function(response, status, xhr) {
if (this._request !== xhr) return; // aborted
// success
}.bind(this)).done(this._freeRequest.bind(this));
}
_freeRequest: function() {
if (this._request) {
delete this._request;
}
}
Llamar a doRequest
nuevamente o _freeRequest
una vez antes de que se complete la solicitud anterior, resultará en el "aborto" de dicha solicitud al hacer que la línea if (this._request !== xhr)
se convierta en verdadera, ya que this._request
se eliminará o Otra petición en conjunto.
jsonpString anula el nombre de la función de devolución de llamada en una solicitud jsonp. Este valor se utilizará en lugar de ''devolución de llamada'' en el ''devolución de llamada =?'' parte de la cadena de consulta en la URL.
Entonces {jsonp:''onJSONPLoad''}
resultaría en ''onJSONPLoad=?''
Pasado al servidor. A partir de jQuery 1.5, establecer la opción jsonp en falso evita que jQuery agregue la cadena ?callback
a la URL o intente usar =?
para la transformación. En este caso, también debe establecer explícitamente la configuración jsonpCallback
. Por ejemplo, { jsonp: false, jsonpCallback: "callbackName" }
http://api.jquery.com/jQuery.ajax/
jQuery agrega ?callback=jQuery17109492628197185695_1339420031913
y luego configura los datos de solicitud como parámetro para esta devolución de llamada, por lo que tendrá:
jQuery17109492628197185695_1339420031913({
"status": 200,
"data": {your json}
})
Para evitar establecer parámetros adicionales para solicitar una URL y devolver la llamada, agregue este parámetro al método ajax: jsonp:false
, para que se vea como:
$.ajax({
...
jsonp:false,
...
});
No abortar la solicitud
Simplemente almacene en algún lugar el objeto jqXHR devuelto por $.ajax()
theJqXHR = $.ajax(....
Si el usuario cancela la solicitud nula el objeto guardado.
// user canceled
theJqXHR = null;
Finalmente, cuando reciba la respuesta (devolución de llamada success
), la devolución de llamada comparará el objeto jqXHR de la respuesta con el objeto guardado.
function successCallback(data, textStatus, jqXHR )
{
if( theJqXHR !== jqXHR )
{
// user canceled; discard the response
return;
}
// process the response
}
No hay errores de jQuery.
Como consejo general, no confíe en abort()
, incluso para las solicitudes regulares de ajax.
En cualquier caso, no guardará recursos en el servidor porque la solicitud que envió se procesará y no hay forma de detenerla . Y una respuesta volverá.
Algunos navegadores (más antiguos) manejan
abort()
no correctamente.
Simplemente " caché " el objeto jqXHR y maneje el escenario CANCELAR usted mismo.