Abortar solicitudes de Ajax usando jQuery

¿Es posible que al usar jQuery, cancelar / abortar una solicitud Ajax de la que aún no he recibido respuesta?

preguntado el 15 de enero de 09 a las 13:01

Tal vez he entendido mal la pregunta, pero ¿no podrías simplemente usar $.ajaxStop? -

@LukeMadhanga; creo ajaxStop solo detecta cuando todas las solicitudes AJAX están completas, no detiene una solicitud. En mi experiencia, lo usaría así: $(document).ajaxStop(function(){alert("All done")}). Utilizando .abort() es la mejor opción. -

18 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()

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

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 aún 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 correcta. Más información sobre el repositorio jQuery Github.

Respondido 15 Jul 18, 01:07

Es como hacer clic en el botón "detener" de su navegador. Cancela la solicitud. Luego, puede reutilizar el mismo objeto XHR para otra solicitud. - maullar

@brad Desafortunadamente, abort no cierra una conexión establecida con el servidor, por lo que success todavía se llamará. Esto es muy problemático para las implementaciones de Comet con un sondeo largo. - pepkin88

@ErvWalter Podrías enviar otra solicitud que cancele la anterior. - Asad Saeeduddin

En mis pruebas, la solicitud se cancela en el navegador, pero el método .fail () se invoca con un jqXHR, status = 0 y jqXHR, statusMessage = "abort" - BJ Safdie

.abort() todavía me funciona en jQuery 3.2.1. Esto comentar en un problema de github relacionado por un miembro del equipo central de jQuery parece implicar que esta respuesta es incorrecta y que .abort() no fue eliminado. - alarmante

No puede recordar la solicitud, pero puede establecer un valor de tiempo de espera después del 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 AJAX.

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

Respondido 03 Jul 12, 04:07

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

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

De lo contrario, simplemente ignore la respuesta AJAX.

Respondido el 15 de enero de 09 a las 15:01

En este contexto, asincrónico simplemente significa que la solicitud no interrumpe el flujo del script. Los navegadores ahora tienen la capacidad de cancelar la solicitud prematuramente antes de que se complete la solicitud. - ElefanteCazador

¿Cómo podemos enviar una solicitud de cancelación al servidor? No entiendo cómo el servidor sabrá qué solicitud dejar de procesar. ¿Podría darnos un ejemplo? Gracias. - Suerte Soni

@LuckySoni, Elephanthunter solo está hablando del lado del cliente. El servidor no se verá afectado por una solicitud .abort - Kloar

@Kloar, si el servidor aún no ha recibido la solicitud (por ejemplo, solicitudes grandes de varias partes), el cliente puede cerrar el socket y el servidor se verá afectado. - blanco

PHP comprueba automáticamente las solicitudes abortadas y también termina automáticamente. ver php.net/manual/en/function.ignore-user-abort.php - Hanshenrik

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

PRECAUCIÓN ENORME: 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 finaliza el ajax. Entonces, para permitir que el usuario continúe navegando por 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 a que se elimine el candado.

Respondido 13 ago 13, 19:08

ya que siempre cancelas el anterior, ¿no puedes hacer eso siempre? (y no es necesario usar una matriz) - no polaridad

Es posible que las solicitudes AJAX no se completen en el orden en que se iniciaron. En lugar de abortar, puede optar por pasar por alto todas las respuestas AJAX excepto la más reciente:

  • Crea un contador
  • Incrementa el contador cuando inicias la solicitud AJAX
  • Utilice 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

respondido 18 mar '15, 10:03

Debido a las advertencias de cancelar una solicitud XHR (ver otros comentarios en esta página), esta es probablemente la mejor y más simple opción. - Quinn acusado

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

  1. cancela la solicitud como lo sugiere @meouw
  2. ejecutar todas las solicitudes pero solo procesa el resultado del último envío
  3. evita 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 jQuery garantice la llamada del método .complete (), esto podría producir una situación de punto muerto. En nuestras pruebas no pudimos reproducir tal situación.

Respondido 28 ago 17, 19:08

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 verifica una declaración if para verificar si la solicitud ajax es nula o no.

Respondido 15 Oct 14, 13:10

También verifico si ya se está ejecutando una solicitud, pero uso un booleano, ya que es más ligero. - zesty

Simplemente llame a xhr.abortar() ya sea un objeto jquery ajax o un objeto XMLHTTPRequest nativo.

ejemplo:

//jQuery ajax
$(document).ready(function(){
    var xhr = $.get('/server');
    setTimeout(function(){xhr.abort();}, 2000);
});

//native XMLHTTPRequest
var xhr = new XMLHttpRequest();
xhr.open('GET','/server',true);
xhr.send();
setTimeout(function(){xhr.abort();}, 2000);

Respondido 10 Jul 18, 11:07

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

En mi caso usé 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 

Respondido el 04 de diciembre de 13 a las 18:12

Como han señalado muchas personas en el hilo, solo porque la solicitud se cancela en el lado del cliente, el servidor seguirá procesando la solicitud. Esto crea una carga innecesaria en el servidor porque está haciendo un trabajo que dejamos de escuchar en el front-end.

El problema que estaba tratando de resolver (que otros pueden encontrar también) es que cuando el usuario ingresó información en un campo de entrada, quería enviar una solicitud para un tipo de sensación de Google Instant.

Para evitar disparar solicitudes innecesarias y mantener la agilidad del front-end, hice lo siguiente:

var xhrQueue = [];
var xhrCount = 0;

$('#search_q').keyup(function(){

    xhrQueue.push(xhrCount);

    setTimeout(function(){

        xhrCount = ++xhrCount;

        if (xhrCount === xhrQueue.length) {
            // Fire Your XHR //
        }

    }, 150);

});

Básicamente, esto enviará una solicitud cada 150 ms (una variable que puede personalizar para sus propias necesidades). Si tiene problemas para comprender qué está sucediendo exactamente aquí, inicie sesión xhrCount y xhrQueue a la consola justo antes del bloque if.

Respondido 03 Feb 14, 22:02

Puede abortar cualquier llamada ajax continua usando esto

<input id="searchbox" name="searchbox" type="text" />

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
     var request = null;
        $('#searchbox').keyup(function () {
            var id = $(this).val();
            request = $.ajax({
                type: "POST", //TODO: Must be changed to POST
                url: "index.php",
                data: {'id':id},
                success: function () {
    
                },
                beforeSend: function () {
                    if (request !== null) {
                        request.abort();
                    }
                }
            });
        });
</script>

respondido 23 nov., 20:15

Simplemente use ajax.abort () por ejemplo, podría abortar cualquier solicitud de ajax pendiente antes de enviar otra como esta

//check for existing ajax request
if(ajax){ 
 ajax.abort();
 }
//then you make another ajax request
$.ajax(
 //your code here
  );

respondido 08 nov., 13:12

no hay una forma confiable de hacerlo, y ni siquiera lo probaría, una vez que la solicitud esté en marcha; la , el CTC forma de reaccionar razonablemente es pasar por alto la respuesta.

en la mayoría de los casos, puede suceder en situaciones como: un usuario hace clic con demasiada frecuencia en un botón que activa muchos XHR consecutivos, aquí tiene muchas opciones, bloquear el botón hasta que se devuelva XHR o ni siquiera activar un nuevo XHR mientras otro está ejecutando sugerencias que el usuario se recueste, o descarte cualquier respuesta XHR pendiente que no sea la reciente.

Respondido el 17 de junio de 15 a las 21:06

El siguiente código muestra el inicio y el aborto de una solicitud Ajax:

function libAjax(){
  var req;
  function start(){

  req =    $.ajax({
              url: '1.php',
              success: function(data){
                console.log(data)
              }
            });

  }

  function stop(){
    req.abort();
  }

  return {start:start,stop:stop}
}

var obj = libAjax();

 $(".go").click(function(){


  obj.start();


 })



 $(".stop").click(function(){

  obj.stop();


 })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" class="go" value="GO!" >
   <input type="button" class="stop" value="STOP!" >

Respondido el 26 de Septiembre de 17 a las 17:09

Proporcione una explicación de cómo esto resuelve la pregunta. Esto ayudará al OP y a otros buscadores futuros. - SnareChops

Tuve el problema de la encuesta y una vez que se cerró la página, la encuesta continuó, por lo que, por mi causa, un usuario se perdería una actualización ya que se estaba estableciendo un valor de mysql para los siguientes 50 segundos después del cierre de la página, aunque eliminé la solicitud de ajax, calculado, usar $ _SESSION para configurar una var no se actualizará en la encuesta hasta que finalice y haya comenzado una nueva, así que lo que hice fue establecer un valor en mi base de datos como 0 = fuera de página, mientras estoy sondeo, consulto esa fila y devuelvo falso; cuando es 0, ya que la consulta en el sondeo obtendrá los valores actuales, obviamente ...

Espero que esto ayude

Respondido 25 Jul 13, 16:07

If xhr.abort(); provoca la recarga de la página,

Entonces puedes configurar onreadystatechange antes de abortar para prevenir:

// ↓ prevent page reload by abort()
xhr.onreadystatechange = null;
// ↓ may cause page reload
xhr.abort();

Respondido 23 Oct 16, 14:10

He compartido un manifestación que demuestra cómo cancelar una solicitud AJAX, si los datos no se devuelven desde el servidor dentro de un tiempo de espera predefinido.

HTML:

<div id="info"></div>

CÓDIGO JS:

var isDataReceived= false, waitTime= 1000; 
$(function() {
    // Ajax request sent.
     var xhr= $.ajax({
      url: 'http://api.joind.in/v2.1/talks/10889',
      data: {
         format: 'json'
      },     
      dataType: 'jsonp',
      success: function(data) {      
        isDataReceived= true;
        $('#info').text(data.talks[0].talk_title);        
      },
      type: 'GET'
   });
   // Cancel ajax request if data is not loaded within 1sec.
   setTimeout(function(){
     if(!isDataReceived)
     xhr.abort();     
   },waitTime);   
});

Respondido 12 Feb 16, 08:02

$.ajax proporciona una timeout opción para que no tenga que escribir la suya propia. Simplemente use ..., data: {...}, timeout: waitTime,.... - Bram Vanroy

Esta es mi implementación basada en muchas respuestas anteriores:

  var activeRequest = false; //global var
  var filters = {...};
  apply_filters(filters);

  //function triggering the ajax request
  function apply_filters(filters){
        //prepare data and other functionalities
        var data = {};
        //limit the ajax calls
        if (activeRequest === false){
          activeRequest = true;
        }else{
          //abort if another ajax call is pending
          $request.abort();
          //just to be sure the ajax didn't complete before and activeRequest it's already false
          activeRequest = true;        
        }

        $request = $.ajax({ 
          url : window.location.origin + '/your-url.php',
          data: data,
          type:'POST',
          beforeSend: function(){
            $('#ajax-loader-custom').show();
            $('#blur-on-loading').addClass('blur');
          },            
          success:function(data_filters){

              data_filters = $.parseJSON(data_filters);
              
              if( data_filters.posts ) {
                  $(document).find('#multiple-products ul.products li:last-child').after(data_filters.posts).fadeIn();
              }
              else{ 
                return;
              }
              $('#ajax-loader-custom').fadeOut();
          },
          complete: function() {
            activeRequest = false;
          }          
        }); 
  } 

Respondido 24 Feb 21, 19:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.