20

Отмена Ajax-запросов с помощью jQuery

18

Вопрос:

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

5 ответ(ов)

0

Чтобы сохранить вызовы, которые вы делаете, в массиве, а затем вызвать xhr.abort() для каждого из них, вы можете воспользоваться следующим подходом:

let requests = [];

// Пример функции, выполняющей AJAX-запрос
function makeRequest(url) {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url);

    // Сохраняем запрос для последующего прерывания
    requests.push(xhr);

    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            // Обработка ответа
            if (xhr.status === 200) {
                console.log(xhr.responseText);
            }
        }
    };

    xhr.send();
}

// Прерывание всех запросов
function abortAllRequests() {
    requests.forEach(xhr => xhr.abort());
    requests = []; // Очищаем массив после прерывания
}

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

0

Это асинхронный запрос, что означает, что после его отправки он уже «вне» вашего контроля.

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

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

0

Наилучшей практикой является использование следующего кода:

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

$request = $.ajax({
    type: "POST", // TODO: Нужно изменить на POST
    url: "yourfile.php",
    data: "data"
}).done(function(msg) {
    alert(msg);
});

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

0

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

  1. Обрабатываем отмену запроса, как предложил @meouw.
  2. Выполняем все запросы, но обрабатываем только результат последнего.
  3. Предотвращаем новые запросы, пока предыдущий ещё выполняется.
var Ajax1 = {
  call: function() {
    if (typeof this.xhr !== 'undefined')
      this.xhr.abort();
    this.xhr = $.ajax({
      url: 'ваш/долгий/запрос/путь',
      type: 'GET',
      success: function(data) {
        // обработка ответа
      }
    });
  }
};

var Ajax2 = {
  counter: 0,
  call: function() {
    var self = this,
      seq = ++this.counter;
    $.ajax({
      url: 'ваш/долгий/запрос/путь',
      type: 'GET',
      success: function(data) {
        if (seq === self.counter) {
          // обработка ответа
        }
      }
    });
  }
};

var Ajax3 = {
  active: false,
  call: function() {
    if (this.active === false) {
      this.active = true;
      var self = this;
      $.ajax({
        url: 'ваш/долгий/запрос/путь',
        type: 'GET',
        success: function(data) {
          // обработка ответа
        },
        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="нажми" />

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

0

Вы можете просто вызвать xhr.abort(), независимо от того, используете ли вы объект Ajax из jQuery или nativный объект XMLHttpRequest.

Вот пример кода:

// Ajax с использованием jQuery
$(document).ready(function(){
    var xhr = $.get('/server');
    setTimeout(function(){ xhr.abort(); }, 2000);
});

// Нативный XMLHttpRequest
var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);
xhr.send();
setTimeout(function(){ xhr.abort(); }, 2000);

В данном примере мы выполняем запрос на сервер, а затем через 2 секунды прерываем его с помощью метода abort().

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь