Изменить страницу в середине запроса Ajax - PullRequest
12 голосов
/ 02 августа 2011

Что произойдет, если я отправлю какой-нибудь ajax-запрос и сразу же изменю страницу (скажем, перейдите по какой-либо ссылке), прежде чем запрос вернется? Я имею в виду, я предполагаю, что объект XHR отправляет запрос на веб-сайт, но он удаляется (поскольку страница изменилась) до получения ответа, так куда же следует отправлять ответ?

Я задаю этот вопрос, потому что у меня странная проблема с моим сайтом. У меня есть страница, которая загружает сообщения из хранилища данных по запросу Ajax. Если до завершения загрузки я нажимаю на ссылку, вызывается ошибка jQuery.ajax! Не уверен, почему это происходит.

РЕДАКТИРОВАТЬ : Это мой призыв к Ajax. В обычном случае вызывается обратный вызов успеха. Но когда я нажимаю на ссылку, вызывается обратный вызов ошибки! Я думаю о чем-то, может ли это быть потому, что данные должны быть отформатированы как JSON, но запрос обрезается посередине, поэтому данные считаются неверными, в результате чего jQuery вызывает обратный вызов ошибки ?! Но тогда почему запросы обрезаются посередине?

$.ajax({
  type: (args.rel == "async" || args.rel == "dialog") ? "GET" : "POST",
  url: href,
  dataType: "json",
  data: args.data ? args.data:{}, // send {} to ensure Content-Length header
  success: function(data){
    if (context) context.removeClass("ajax_wait");
    if (args.hideonwait) $(args.hideonwait).show();
    if (args.showonwait) $(args.showonwait).hide();
    if (spinner) remove_spinner(context, spinner);
    handle_response(args, context, target, data);
  },
  error: function(xhr, status, errorThrown){
    if (context) context.removeClass("ajax_wait");
    if (args.hideonwait) $(args.hideonwait).show();
    if (args.showonwait) $(args.showonwait).hide();
    if (spinner) remove_spinner(context, spinner);
    ajax_error(args, context,
               status + "-" + xhr.status,
               errorThrown ? errorThrown : xhr.responseText);
  }
});

Ответы [ 5 ]

10 голосов
/ 30 января 2013

Хитрость заключается в проверке заголовков ответов в объекте XMLHttpRequest.Если заголовки ответа отсутствуют (пустая или пустая строка, в зависимости от браузера), сервер еще не ответил.Это означает, что пользователь прервал.

$.ajax({
    url: "url-to-go-here",
    success: function() {
    },
    error: function(xhr, textStatus, errorThrown) {
        if(!isUserAborted(xhr)) {
            console.log("Ajax Error")
        }
    }
});

function isUserAborted(xhr) {
  return !xhr.getAllResponseHeaders();
}

Источник

3 голосов
/ 21 июня 2012

Поведение выглядит так, когда пользователь покидает страницу, любые ожидающие запросы ajax завершаются с 0 в качестве их статуса. jQuery интерпретирует это как ошибку, поэтому вызывает обработчик ошибок. В вашем обработчике ошибок вы можете вызывать ту же функцию, что и ваш обработчик успеха, если xhr.status == 0, в противном случае выполнить требуемое поведение ошибки.

1 голос
/ 25 июня 2012

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

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

Надеюсь, что это отвечает на вопрос.

0 голосов
/ 04 июля 2013

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

var message = '';
$('whatever').ajaxError(function(e, xhr, settings, exception) {
  // logic
   if (!xhr.status){
      if (exception=='abort'){
         message = 'User aborted AJAX request !'; 
      }
   }
}
0 голосов
/ 02 августа 2011

Тебе бы не повезло.У вас не будет обратного вызова, чтобы вернуться.Ответ Ajax будет потерян.В этом случае я бы поставил блокировщик на странице.Это довольно часто, чтобы предотвратить еще один щелчок.Блокировщик не более чем большая маска, которая «накладывается» на весь браузер.Также может быть иконка ожидания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...