пятница, 23 января 2015 г.

Ajax запрос и ошибка при перезагрузке страницы

Всем привет,

Возможно вы сталкивались с ситуацией, когда вы делаете ajax запрос, он долго орабатывается на сервере и вы перегружаете страницу в надежде, что следующий раз он выполнится быстрей, но нет :) вы получаете ошибку.
Ниже пример такого запроса:
$.getJSON("/clients/list")
    .success(function(){ ... })
    .error(function(xhr, error, statusText){
 // ошибка выпадает здесь
    })

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

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

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

Когда у вас ajax запрос выполняется с ошибкой, у вас в обработчике нет никаких флагов и полей, которые говорят почему запрос не полнился. В документации к jquery http://api.jquery.com/jQuery.ajax/ пишут, что в поле error (в моем примере) будет статус запроса. На практике такого не было. Напишите в коментариях, если у вас статусы работают.

Теперь решение.
Если запрос выполнился, но с ошибкой (на сервере), вы получите полноценный HTTP ответ с хедерами и телом ответа, не важно каким. Но, если запрос был прерван - вы не получите HTTP ответ, следовательно вы не получите ни хедеры, ни тело ответа. Все :)

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

Код с решением:
var isUserAbortedRequest = function (xhr) {
    return !xhr.getAllResponseHeaders();
}

$.getJSON("/clients/list")
    .success(function(){ ... })
    .error(function(xhr, error, statusText){
 if (!isUserAbortedRequest(xhr)) {
     // показаем ошибку
        } else {
     // ничего не показываем, перезагрузка или переход на другую страницу
        } 
    })

Комментариев нет:

Отправить комментарий