Pregunta Abortar solicitudes Ajax usando jQuery


Usando jQuery, ¿cómo puedo cancelar / abortar una solicitud de Ajax de que aún no he recibido la respuesta?


1633
2018-01-15 12:45


origen


Respuestas:


La mayoría de los métodos jQuery Ajax devuelven un objeto XMLHttpRequest (o el equivalente), por lo que puede usar abort().

Ver la documentación:

var xhr = $.ajax({
    type: "POST",
    url: "some.php",
    data: "name=John&location=Boston",
    success: function(msg){
       alert( "Data Saved: " + msg );
    }
});

//kill the request
xhr.abort()

ACTUALIZAR: A partir de jQuery 1.5, el objeto devuelto es un contenedor para el objeto nativo XMLHttpRequest llamado jqXHR. Este objeto parece exponer todas las propiedades y métodos nativos para que el ejemplo anterior aún funcione. Ver El objeto jqXHR (documentación de jQuery API).

ACTUALIZACIÓN 2: A partir de jQuery 3, el método ajax ahora devuelve una promesa con métodos adicionales (como abortar), por lo que el código anterior todavía funciona, aunque el objeto que se devuelve no es un xhr nunca más. Ver el 3.0 blog aquí.

ACTUALIZACIÓN 3: xhr.abort() todavía funciona en jQuery 3.x. No asuma el actualización 2 es correcto. Más información en el repositorio jQuery Github.


1592
2018-01-15 12:56



No puede recuperar la solicitud pero puede establecer un valor de tiempo de espera después de lo cual se ignorará la respuesta. Mira esto página para las opciones de jquery AJAX. Creo que se llamará a su devolución de llamada de error si se excede el período de tiempo de espera. Ya existe un tiempo de espera predeterminado en cada solicitud de AJAX.

También puedes usar el abortar() método en el objeto de solicitud pero, aunque hará que el cliente deje de escuchar el evento, mayo probablemente no evitará que el servidor lo procese.


106
2018-01-15 12:55



Se trata de un asincrónico solicitud, lo que significa que una vez que se envía está disponible.

En caso de que su servidor esté comenzando una operación muy costosa debido a la solicitud de AJAX, lo mejor que puede hacer es abrir su servidor para escuchar solicitudes de cancelación y enviar una solicitud AJAX por separado notificando al servidor que detenga lo que sea que esté haciendo.

De lo contrario, simplemente ignore la respuesta AJAX.


70
2018-01-15 12:56



Guarde las llamadas que hace en una matriz, luego llame a xhr.abort () en cada una.

ENORME CAVEAT: puede cancelar una solicitud, pero eso es solo del lado del cliente. El lado del servidor aún podría estar procesando la solicitud. Si está utilizando algo como PHP o ASP con datos de sesión, los datos de la sesión se bloquean hasta que el ajax haya finalizado. Entonces, para permitir que el usuario continúe navegando en el sitio web, debe llamar session_write_close(). Esto guarda la sesión y la desbloquea para que otras páginas que esperan continuar continúen. Sin esto, varias páginas pueden estar esperando que se elimine el bloqueo.


62
2018-03-28 11:34



Las solicitudes AJAX pueden no completarse en el orden en que se iniciaron. En lugar de abortar, puede elegir ignorar todas las respuestas AJAX excepto la más reciente:

  • Crea un contador
  • Incremente el contador cuando inicie la solicitud de AJAX
  • Use el valor actual del contador para "sellar" la solicitud
  • En la devolución de llamada exitosa, compare el sello con el contador para verificar si fue la solicitud más reciente

Esquema aproximado del código:

var xhrCount = 0;
function sendXHR() {
    // sequence number for the current invocation of function
    var seqNumber = ++xhrCount;
    $.post("/echo/json/", { delay: Math.floor(Math.random() * 5) }, function() {
        // this works because of the way closures work
        if (seqNumber === xhrCount) {
            console.log("Process the response");
        } else {
            console.log("Ignore the response");
        }
    });
}
sendXHR();
sendXHR();
sendXHR();
// AJAX requests complete in any order but only the last 
// one will trigger "Process the response" message

Demostración en jsFiddle


45
2018-01-18 12:55



Simplemente tuvimos que solucionar este problema y probar tres enfoques diferentes.

  1. cancela la solicitud según lo sugerido por @meouw
  2. ejecutar todas las solicitudes pero solo procesa el resultado de la última presentación
  3. previene nuevas solicitudes siempre que haya otra pendiente

var Ajax1 = {
  call: function() {
    if (typeof this.xhr !== 'undefined')
      this.xhr.abort();
    this.xhr = $.ajax({
      url: 'your/long/running/request/path',
      type: 'GET',
      success: function(data) {
        //process response
      }
    });
  }
};
var Ajax2 = {
  counter: 0,
  call: function() {
    var self = this,
      seq = ++this.counter;
    $.ajax({
      url: 'your/long/running/request/path',
      type: 'GET',
      success: function(data) {
        if (seq === self.counter) {
          //process response
        }
      }
    });
  }
};
var Ajax3 = {
  active: false,
  call: function() {
    if (this.active === false) {
      this.active = true;
      var self = this;
      $.ajax({
        url: 'your/long/running/request/path',
        type: 'GET',
        success: function(data) {
          //process response
        },
        complete: function() {
          self.active = false;
        }
      });
    }
  }
};
$(function() {
  $('#button').click(function(e) {
    Ajax3.call();
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="button" type="button" value="click" />

En nuestro caso, decidimos utilizar el enfoque n. ° 3 ya que produce menos carga para el servidor. Pero no estoy 100% seguro de que si jQuery garantiza la invocación del método .complete (), esto podría generar una situación de punto muerto. En nuestras pruebas no pudimos reproducir tal situación.


36
2018-03-06 14:29



Siempre es una buena práctica hacer algo como esto.

var $request;
if ($request != null){ 
    $request.abort();
    $request = null;
}

$request = $.ajax({
    type : "POST", //TODO: Must be changed to POST
    url : "yourfile.php",
    data : "data"
    }).done(function(msg) {
        alert(msg);
    });

Pero es mucho mejor si revisa una instrucción if para verificar si la solicitud de ajax es nula o no.


30
2017-10-15 09:14



la solución de meouw es correcto, pero si estás interesado en tener más control, entonces podrías probar Plugin Ajax Manager para jQuery.


19
2018-01-15 15:45



Estaba haciendo una solución de búsqueda en vivo y necesitaba cancelar las solicitudes pendientes que pueden haber tomado más tiempo que la última solicitud o la más reciente.

En mi caso, utilicé algo como esto:

//On document ready
var ajax_inprocess = false;

$(document).ajaxStart(function() {
ajax_inprocess = true;
});

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

//Snippet from live search function
if (ajax_inprocess == true)
{
    request.abort();
}
//Call for new request 

11
2017-12-04 14:43