2011-06-24 18 views
16

Estoy usando una llamada JSONP ajax para cargar contenido de un dominio diferente, y todo esto se ejecuta si el usuario causa un "mouseover" en un botón.Anula la solicitud JEAP ajax con jQuery

Puedo capturar el retorno de llamada $ .ajax() como un objeto xhr, y usarlo para abortar la solicitud ajax cada vez que el usuario causa un "mouseover". Pero todavía se llama a la función de devolución de llamada JSONP, 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í (de acuerdo con Firebug): jQuery16102234208755205157_1308941669256 no es una función

y la estructura interna de la excepción es la siguiente: jQuery16102234208755205157_1308941669256 ({... mis datos JSON de una dominio diferente ...})

+0

posible duplicado de [Mata las solicitudes ajax usando javascript usando jquery.] (Http://stackoverflow.com/questions/446594/kill-ajax-requests-using-javascript-using-jquery) – Neal

+3

Supongo que esto no es así duplicar, porque esta pregunta se trata de evitar una excepción después de invocar el método jqxhr.abort() en una solicitud JSONP ajax, no de cómo detener la solicitud en sí. –

+0

La respuesta a esta pregunta se puede encontrar en la pregunta duplicada http: // stackoverflow.com/questions/9533848/aborting-jquery-jsonp-request-will-throw-error –

Respuesta

-2

En jQuery 1.5 todas las API Ajax tienen un objeto contenedor alrededor de los objetos XHR nativos. Echar un vistazo a:

http://api.jquery.com/jQuery.ajax/#jqXHR

jqxhr.abort(); // should be what you're looking for 
+2

Esto es lo que estoy usando ahora mismo. Esto aborta la solicitud de Ajax. Pero esta solicitud ajax usa JSONP. Después de usar el método "abort()", se invoca una función de JavaScript generada internamente por jQuery para manejar la respuesta JSONP, pero el método de aborto parece eliminar esa definición de función, o algo así, porque hay una excepción que no he sido capaz de manejar. –

+0

¿Tiene más información? ejemplo en vivo, mensaje de excepción? –

11

La respuesta básica es simplemente la dada here: Usted no puede realmente abort() una llamada JSONP. Entonces, la verdadera pregunta es, ¿cómo se evitan las invocaciones de devolución de llamada superfluas y el error que está viendo?

No se puede usar 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 lanzadas desde las 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 invoque la devolución exitosa, compruebe si ese identificador es el mismo que cuando hizo la llamada . He aquí una aplicació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 tomando ventaja del hecho de que cualquier cosa que pase a $.ajax se une al objeto que se utiliza como this en la devolución de llamada.

Sería bueno si jQuery hizo abort() hacer esto por nosotros, por supuesto.

1

jsonpString anula el nombre de la función de devolución de llamada en una solicitud jsonp. Este valor se usará en lugar de 'devolución de llamada' en 'callback =?' parte de la cadena de consulta en la URL.

Así que {jsonp:'onJSONPLoad'} daría como resultado 'onJSONPLoad=?' pasado al servidor. A partir de jQuery 1.5, establecer la opción jsonp en false evita que jQuery agregue la cadena ?callback a la URL o que intente utilizar =? 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 añade ?callback=jQuery17109492628197185695_1339420031913 y posteriormente establece los datos de la solicitud como parámetro a esta devolución de llamada, por lo que tendrá:

jQuery17109492628197185695_1339420031913({ 
    "status": 200, 
    "data": {your json} 
}) 

Para evitar el establecimiento de parámetros adicionales para solicitar una URL y Llamada de devolución de llamada, agregue este parámetro al método ajax: jsonp:false, por lo que se verá como:

$.ajax({ 
    ... 
    jsonp:false, 
    ... 
}); 
0

La respuesta de Trevor Burnham es bastante buena, pero en lugar de rastrear un recuento de solicitudes, simplemente 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; 
    } 
} 

Calling doRequest de nuevo o _freeRequest una vez antes de la solicitud anterior haya completado, dará lugar a la "aborto" de dicha petición al hacer que la línea if (this._request !== xhr) a llegar a ser verdad, ya que this._request se eliminarán o otra solicitud por completo.

1

No abortar la solicitud

tienda sólo alguna parte del XHR objeto

theXHR = $.ajax(.... 

Si el usuario cancela la solicitud nula del objeto guardado

// user canceled 
theXHR = null; 

Finalmente cuando recibir la respuesta (success devolución de llamada) la devolución de llamada wi Comparará el objeto XHR de la respuesta con el objeto guardado.

function successCallback(data, textStatus, XHR) 
{ 
    if(theXHR !== XHR) 
    { 
     // user canceled; discard the response 
     return; 
    } 

    // process the response 
} 

No jQuery errors.


Como consejo general no confiar en abort(), incluso para peticiones Ajax regulares.

  1. En cualquier caso, no se ahorrará recursos en el servidor dispensada la solicitud que envió será procesada y no hay manera de detenerlo. Y una respuesta regresará.

  2. Algunos navegadores (antiguos) manejan abort() incorrectamente.

Justo " caché" el objeto XHR y manipular el CANCELAR escenario mismo.

Cuestiones relacionadas