Вопрос: Отменить запросы Ajax с помощью jQuery


Использование jQuery, как я могу отменить / прервать запрос Ajax что я еще не получил ответ?


1622


источник


Ответы:


Большинство методов jQuery Ajax возвращают объект XMLHttpRequest (или эквивалентный), поэтому вы можете просто использовать abort(),

См. Документацию:

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

ОБНОВИТЬ: С jQuery 1.5 возвращаемый объект является оболочкой для собственного объекта XMLHttpRequest, называемого jqXHR. Этот объект, как представляется, раскрывает все собственные свойства и методы, поэтому приведенный выше пример все еще работает. Видеть Объект jqXHR (документация API jQuery).

ОБНОВЛЕНИЕ 2: Начиная с jQuery 3, метод ajax теперь возвращает обещание с дополнительными методами (например, прерывание), поэтому приведенный выше код все еще работает, хотя возвращаемый объект не является xhrбольше. См. 3.0 блог здесь ,


1579



Вы не можете вспомнить запрос, но вы можете установить значение тайм-аута, после которого ответ будет проигнорирован. Видеть это страница для jQuery AJAX. Я считаю, что ваш обратный вызов будет вызываться, если превышен период ожидания. Для каждого запроса AJAX уже установлен тайм-аут по умолчанию.

Вы также можете использовать прервать () метод на объекте запроса, но, в то время как это заставит клиента прекратить прослушивание события, это май вероятно, не остановит сервер от его обработки.


103



Это асинхронный запрос, то есть, как только он отправлен, он там.

В случае, если ваш сервер начинает очень дорогостоящую операцию из-за запроса AJAX, самое лучшее, что вы можете сделать, это открыть сервер для прослушивания запросов на отмену и отправить отдельный запрос AJAX, уведомляющий сервер, чтобы остановить все, что он делает.

В противном случае просто игнорируйте ответ AJAX.


68



Сохраните вызовы, которые вы делаете в массиве, затем вызовите xhr.abort () для каждого.

HUGE CAVEAT: вы можете прервать запрос, но это только клиентская сторона. Серверная сторона все еще может обрабатывать запрос. Если вы используете что-то вроде PHP или ASP с данными сеанса, данные сеанса блокируются до завершения ajax. Таким образом, чтобы позволить пользователю продолжить просмотр веб-сайта, вам нужно позвонить session_write_close (). Это сохраняет сеанс и разблокирует его, чтобы продолжить работу других страниц, ожидающих продолжения. Без этого несколько страниц могут ждать блокировки.


60



Запросы AJAX могут не выполняться в том порядке, в котором они были запущены. Вместо прерывания вы можете выбрать игнорировать все ответы AJAX, за исключением последнего:

  • Создать счетчик
  • Увеличение счетчика при запуске запроса AJAX
  • Использовать текущее значение счетчика для «штампа» запроса
  • В обратном вызове успеха сравните штамп со счетчиком, чтобы проверить, был ли он самым последним запросом

Грубая схема кода:

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

Демо на jsFiddle


39



Нам просто нужно было решить эту проблему и протестировать три разных подхода.

  1. отменяет запрос в соответствии с предложением @meouw
  2. выполнять весь запрос, но обрабатывает только результат последнего отправления
  3. предотвращает новые запросы до тех пор, пока еще один

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" />

В нашем случае мы решили использовать подход № 3, поскольку он создает меньшую нагрузку для сервера. Но я не уверен на 100%, если jQuery гарантирует вызов метода .complete (), это может вызвать тупиковую ситуацию. В наших тестах мы не смогли воспроизвести такую ​​ситуацию.


33



It is always best practice to do something like this.

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);
    });

But it is much better if you check an if statement to check whether the ajax request is null or not.


30



meouw's solution is correct, but if you're are interested in more control then you could try the Ajax Manager plugin for jQuery.


19