Прервать Ajax-запросы, используя jQuery

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

вопрос задан 15.01.2009
lukewm
9037 репутация

18 ответов


  • 1611 рейтинг

    Большинство методов 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 (документация по jQuery API).

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

    ОБНОВЛЕНИЕ 3 : xhr.abort() по-прежнему работает на jQuery 3. Икс. Не думайте, что обновление 2 является правильным. Дополнительная информация о хранилище jQuery Github .

    ответ дан meouw, с репутацией 35519, 15.01.2009
  • 107 рейтинг

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

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

    ответ дан tvanfosson, с репутацией 416703, 15.01.2009
  • 70 рейтинг

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

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

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

    ответ дан Yuval Adam, с репутацией 106785, 15.01.2009
  • 62 рейтинг

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

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

    ответ дан Tei, с репутацией 1242, 28.03.2012
  • 45 рейтинг

    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

    ответ дан Salman A, с репутацией 165526, 18.01.2014
  • 37 рейтинг

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

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

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

    ответ дан oyophant, с репутацией 681, 6.03.2013
  • 30 рейтинг

    Всегда лучше делать что-то подобное.

    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 нулевым или нет.

    ответ дан Tharindu Kumara, с репутацией 3341, 15.10.2014
  • 19 рейтинг

    Решение meouw верное, но если вы заинтересованы в большем контроле, вы можете попробовать плагин Ajax Manager для jQuery.

    ответ дан Prestaul, с репутацией 63998, 15.01.2009
  • 11 рейтинг

    Просто позвоните xhr. abort () , будь то объект 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);
    
    ответ дан cuixiping, с репутацией 10175, 28.05.2015
  • 11 рейтинг

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

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

    //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 
    
    ответ дан Billy, с репутацией 111, 4.12.2013
  • 10 рейтинг

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

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

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

    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.

    ответ дан brianrhea, с репутацией 992, 3.02.2014
  • 8 рейтинг

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

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

    ответ дан comeGetSome, с репутацией 1559, 17.06.2015
  • 8 рейтинг

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

    //check for existing ajax request
    if(ajax){ 
     ajax.abort();
     }
    //then you make another ajax request
    $.ajax(
     //your code here
      );
    
    ответ дан Joecoder001, с репутацией 219, 8.11.2013
  • 5 рейтинг

    Следующий код показывает, как инициировать, так и прерывать 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();
    
    
     })
    
    
    
    
       
    
    ответ дан zloctb, с репутацией 4416, 4.01.2016
  • 4 рейтинг

    У меня была проблема с опросом, и как только страница была закрыта, опрос продолжался, поэтому в моем случае пользователь пропустил обновление, поскольку в течение следующих 50 секунд после закрытия страницы устанавливалось значение mysql, даже если я убил запрос ajax, Я сообразил, что использование $ _SESSION для установки переменной не будет обновляться в самом опросе до тех пор, пока он не закончится и не начнется новый, поэтому в моей базе данных было установлено значение 0 = offpage, в то время как я ' m опрашивая, я запрашиваю эту строку и возвращаю false; когда он равен 0, запрос при опросе, очевидно, даст вам текущие значения. , ,

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

    ответ дан Marcus, с репутацией 41, 25.07.2013
  • 3 рейтинг

    Вы можете прервать любой непрерывный вызов AJAX, используя этот

    
    
    
    
    
    
    ответ дан Soubhagya Kumar, с репутацией 252, 18.05.2018
  • 2 рейтинг

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

    HTML:

    
    

    КОД 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);   
    });
    
    ответ дан ganesh, с репутацией 120, 12.02.2016
  • 2 рейтинг

    Если xhr.abort(); вызывает перезагрузку страницы,

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

    // ↓ prevent page reload by abort()
    xhr.onreadystatechange = null;
    // ↓ may cause page reload
    xhr.abort();
    
    ответ дан vikyd, с репутацией 141, 23.10.2016