Изменить страницу в середине запроса Ajax
Что произойдет, если я отправлю какой-либо запрос ajax и сразу же изменю страницу (скажем, следуйте по какой-либо ссылке) до того, как запрос вернется? Я имею в виду, я предполагаю, что объект XHR отправляет запрос на веб-сайт, но он удаляется (поскольку страница изменена) до получения ответа, поэтому где ответ должен быть отправлен?
Я задаю этот вопрос, потому что у меня возникла странная проблема с моим сайтом. У меня есть страница, которая загружает сообщения из хранилища данных через запрос Ajax. Если до завершения загрузки я нажимаю ссылку, я получаю onerror jQuery.ajax, вызываемый! Не знаю, почему это происходит.
EDIT: Это мой призыв к 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);
}
});
Ответы
Ответ 1
Трюк заключается в проверке заголовков ответов в объекте 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();
}
Источник
Ответ 2
Поведение, похоже, происходит, когда пользователь оставляет страницу, любые выдающиеся аякс-запросы с 0 в качестве их статуса. jQuery интерпретирует это как ошибку, поэтому он вызывает обработчик ошибок. В обработчике ошибок вы можете вызвать ту же функцию, что и ваш обработчик успеха, если xhr.status == 0, в противном случае выполните требуемое поведение ошибки.
Ответ 3
Решение этой проблемы прост, все, что вам нужно сделать, - это если запрос выполняется в данный момент, и если пользователь нажимает на любую другую ссылку, тогда вам нужно предупредить пользователя о том, что запрос находится в процессе, пожалуйста, подождите
Для этого вам необходимо поддерживать семафор, установить этот семафор перед тем, как запустить любой запрос, и reset он по завершении этого запроса. При щелчке по каждой ссылке (которая меняет страницу) вызывается метод, который проверяет семафор, и если он установлен, то метод дает вышеупомянутое предупреждение пользователю. Таким образом, пока запрос не завершится, пользователь не сможет изменить страницу, и ваша проблема прерывания запроса будет решена.
Надеюсь, что это ответит на вопрос.
Ответ 4
Вам не повезло. У вас не было бы обратного вызова, чтобы вернуться. Ответ Ajax будет потерян. В этом случае я бы поставил на страницу блокировщик. Это довольно распространено, чтобы предотвратить другой щелчок. Блокатор не более, чем большая маска, которая "закладывает" весь браузер. Он также может иметь значок ожидания.
Ответ 5
Мне приходилось иметь дело с одной и той же проблемой несколько дней назад.. Кажется, что это не так сложно с этим. Мы должны отличить погоду от какой-либо ошибки 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 !';
}
}
}