¿Cómo cancelar / abortar la solicitud jQuery AJAX?

Tengo una solicitud de AJAX que se realizará cada 5 segundos. Pero el problema es antes de la solicitud de AJAX si no se completa la solicitud anterior. Tengo que cancelar esa solicitud y hacer una nueva solicitud.

Mi código es algo como esto, ¿cómo resolver este problema?

$(document).ready( var fn = function(){ $.ajax({ url: 'ajax/progress.ftl', success: function(data) { //do something } }); }; var interval = setInterval(fn, 500); ); 

El método jquery ajax devuelve un objeto XMLHttpRequest . Puede usar este objeto para cancelar la solicitud.

XMLHttpRequest tiene un método abort , que cancela la solicitud, pero si la solicitud ya ha sido enviada al servidor, el servidor procesará la solicitud incluso si cancelamos la solicitud, pero el cliente no esperará / manejará la respuesta.

El objeto xhr también contiene un readyState que contiene el estado de la solicitud (UNSENT-0, OPENED-1, HEADERS_RECEIVED-2, LOADING-3 y DONE-4). podemos usar esto para verificar si la solicitud anterior se completó.

 $(document).ready( var xhr; var fn = function(){ if(xhr && xhr.readyState != 4){ xhr.abort(); } xhr = $.ajax({ url: 'ajax/progress.ftl', success: function(data) { //do something } }); }; var interval = setInterval(fn, 500); ); 

Sé que esto puede ser un poco tarde pero experimento problemas similares donde llamar al método de aborto realmente no abortó la solicitud. en cambio, el navegador todavía estaba esperando una respuesta que nunca usa. este código resolvió ese problema.

  try { xhr.onreadystatechange = null; xhr.abort(); } catch (e) {} 

¿Por qué debería abortar la solicitud?

Si cada solicitud lleva más de cinco segundos, ¿qué sucederá?

No debe cancelar la solicitud si el parámetro que pasa con la solicitud no está cambiando. por ejemplo: – la solicitud es para recuperar los datos de notificación. En tales situaciones, el buen enfoque es establecer una nueva solicitud solo después de completar la solicitud Ajax previa.

 $(document).ready( var fn = function(){ $.ajax({ url: 'ajax/progress.ftl', success: function(data) { //do something }, complete: function(){setTimeout(fn, 500);} }); }; var interval = setTimeout(fn, 500); ); 

Cuando realiza una solicitud a un servidor, haga que compruebe si un progreso no es nulo (o busca esos datos) primero. Si está buscando datos, anule la solicitud anterior e inicie la nueva.

 var progress = null function fn () { if (progress) { progress.abort(); } progress = $.ajax('ajax/progress.ftl', { success: function(data) { //do something progress = null; } }); } 

jQuery: Use esto como punto de partida, como inspiración. Lo resolví así: (esta no es una solución perfecta, solo cancela la última instancia y es código WIP)

 var singleAjax = function singleAjax_constructor(url, params) { // remember last jQuery's get request if (this.lastInstance) { this.lastInstance.abort(); // triggers .always() and .fail() this.lastInstance = false; } // how to use Deferred : http://api.jquery.com/category/deferred-object/ var $def = new $.Deferred(); // pass the deferrer's request handlers into the get response handlers this.lastInstance = $.get(url, params) .fail($def.reject) // triggers .always() and .fail() .success($def.resolve); // triggers .always() and .done() // return the deferrer's "control object", the promise object return $def.promise(); } // initiate first call singleAjax('/ajax.php', {a: 1, b: 2}) .always(function(a,b,c) {console && console.log(a,b,c);}); // second call kills first one singleAjax('/ajax.php', {a: 1, b: 2}) .always(function(a,b,c) {console && console.log(a,b,c);}); // here you might use .always() .fail() .success() etc. 

Puede usar jquery-validate.js. El siguiente es el fragmento de código de jquery-validate.js.

 // ajax mode: abort // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() var pendingRequests = {}, ajax; // Use a prefilter if available (1.5+) if ( $.ajaxPrefilter ) { $.ajaxPrefilter(function( settings, _, xhr ) { var port = settings.port; if ( settings.mode === "abort" ) { if ( pendingRequests[port] ) { pendingRequests[port].abort(); } pendingRequests[port] = xhr; } }); } else { // Proxy ajax ajax = $.ajax; $.ajax = function( settings ) { var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, port = ( "port" in settings ? settings : $.ajaxSettings ).port; if ( mode === "abort" ) { if ( pendingRequests[port] ) { pendingRequests[port].abort(); } pendingRequests[port] = ajax.apply(this, arguments); return pendingRequests[port]; } return ajax.apply(this, arguments); }; } 

De modo que solo necesita configurar el modo de parámetro para abortar cuando realiza una solicitud de jax.

Ref: https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.js

También debe verificar si ReadyState 0. Porque cuando usa xhr.abort () esta función establece readyState en 0 en este objeto, y su verificación if siempre será verdadera – readyState! = 4

 $(document).ready( var xhr; var fn = function(){ if(xhr && xhr.readyState != 4 && xhr.readyState != 0){ xhr.abort(); } xhr = $.ajax({ url: 'ajax/progress.ftl', success: function(data) { //do something } }); }; var interval = setInterval(fn, 500); );