Прерывание Ajax-запросов с помощью jQuery

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

Комментарии к вопросу (2)
Решение

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

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

  • abort Method (MSDN). Отменяет текущий HTTP-запрос.
  • abort() (MDN). Если запрос уже был отправлен, этот метод отменит запрос.
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 (документация jQuery API).

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

ОБНОВЛЕНИЕ 3: xhr.abort() все еще работает на jQuery 3.x. Не думайте, что обновление 2 верно. Больше информации на репозитории jQuery Github.

Комментарии (15)

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

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

Комментарии (0)

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

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

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

Комментарии (8)

Сохранить звонки в массив, затем вызов XHR.метод abort() на каждом.

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

Комментарии (0)

AJAX-запросы могут не выполнять в том порядке, в котором они были запущены. Вместо того, чтобы отменить, вы можете выбрать для ignore все 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][1]

Комментарии (1)

Мы просто должны были работать вокруг этой проблемы и испытаны три различных подхода.

  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 гарантирует зов .выполнить()-метод, это может привести к тупиковой ситуации. В наших тестах мы не смогли воспроизвести такой ситуации.

Комментарии (0)

Это всегда лучшая практика, чтобы сделать что-то подобное.

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

Но это гораздо лучше, если вы проверите оператор if, чтобы проверить, является ли запрос AJAX имеет значение null или нет.

Комментарии (1)

meouw'ный раствор это правильно, но если вы'повторно заинтересованы в больше контроля, то вы могли бы попробовать Аякс менеджер плагинов для jQuery.

Комментарии (1)

Просто вызов XHR.прервать() будь это'объект с помощью jQuery AJAX или родной XMLHttpRequest объекта.

пример:

//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);
Комментарии (0)

Я делал решение прямых поиск и нужно отменять ожидающие запросы, которые, возможно, взяли больше, чем последняя/самая актуальная запросу.

В моем случае я использовал что-то вроде этого:

//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 
Комментарии (0)

Как много людей на теме уже отметил, Просто потому, что запрос прерывается на стороне клиента, сервер будет по-прежнему будет обрабатывать запрос. Это создает ненужную нагрузку на сервер, потому что он'делаешь работу, что мы've прекратили прослушивания на переднем конце.

Проблему я пытался решить (что другие могут работать также), что когда пользователь вводит информацию в поле ввода, я хочу, чтобы запрос для Гугла моментальная типа чувствуют.

Чтобы избежать стрельбы ненужных запросов и поддерживать проворностью переднего плана, я сделал следующее:

var xhrQueue = [];
var xhrCount = 0;

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

    xhrQueue.push(xhrCount);

    setTimeout(function(){

        xhrCount = ++xhrCount;

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

    }, 150);

});

Это, по сути, отправлять один запрос каждые 150 мс (переменной, которую можно настроить под собственные нужды). Если вы'вновь возникли проблемы с пониманием, что именно здесь происходит, журнал xhrCount и `xhrQueue на консоли просто до блока if.

Комментарии (0)

Просто использовать AJAX.метод abort() например, вы могли бы отменить все ожидающие запросы AJAX, прежде чем отправить еще один такой

//check for existing ajax request
if(ajax){ 
 ajax.abort();
 }
//then you make another ajax request
$.ajax(
 //your code here
  );
Комментарии (0)

нет надежного способа сделать это, и я бы не даже попробовать его, как только запрос на ходу; только способ разумно реагировать в игнор ответ.

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

Комментарии (0)

Вы можете прервать любую непрерывную AJAX-вызов с помощью этого

<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>
Комментарии (0)

Следующий код показывает инициирования, а также отменить 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!" >
Комментарии (1)

У меня была проблема голосования и после того, как страница была закрыта, опрос продолжается, так что в моем результате пользователь будет пропустить обновление, как в MySQL значение устанавливается на следующие 50 секунд после закрытия страницы, хотя я убил AJAX-запрос, я понял, что далеко не для всех, с помощью $_SESSION установить ВАР выиграл'т обновления в опросе его собственной, пока его закончился, а новый начался, так что я сделал, было установить значение в моей базе данных как 0 = offpage , в то время как я'м избирательном участке я запрос этой строке и возвращает false; когда он'ы 0 как запрос на избирательных поможет вам текущие значения, очевидно...

Я надеюсь, что это помогло

Комментарии (0)

Я поделился [демо][1], который демонстрирует как отменить AJAX-запрос, если данные не возвращаются от сервера в течение заданного времени ожидания.

HTML-код :

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

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);   
});
Комментарии (1)

Если `то XHR.прервать (); вызывает перезагрузки страницы,

Затем вы можете установить внутренний прежде чем прервать, чтобы предотвратить:

// ↓ prevent page reload by abort()
xhr.onreadystatechange = null;
// ↓ may cause page reload
xhr.abort();
Комментарии (0)