Как стать автором
Обновить

Prototype & Ajax.Request: важный момент при отлове проблем на сервере

Время на прочтение2 мин
Количество просмотров726
Работая над проектом, наш разработчик столкнулся с одной особенностью Prototype, проявляющейся при обработке ошибок Ajax-запросов:

Взгляните на следующий код (используется Prototype 1.6.0.3):

var ajaxReq = new Ajax.Request('Test.jsp', {
     method: 'get',
     onSuccess: function(transport) {
       alert('OK');               
     },
     onFailure: function(transport) {
     	alert('Failure');
     }
});

Вроде бы банальнее некуда, при успешном запросе получаем «ОК», а если сервер выплюнет 404, 500 или что-то вроде этого, тогда «Failure». Все как положено. Однако, угадайте, как поведет себя этот код, если сервер недоступен (грохнулся, например)?

В моем случае, если я прибиваю Tomcat, то этот код выдает…«ОК»! Сразу справедливый вопрос – WTF?

Поиск по докам Prototype дает следующее:
Is the response a successful one?

The success() method examines the XHR's status property, and follows general HTTP guidelines: unknown status is deemed successful, as is the whole 2xy status code family.

Лично для меня такого рода guidelines оказались небольшим сюрпризом. Просмотр HTTP spec показал, что вообще-то status code всегда должен быть и его отсутствие не есть ОК, но возможно разработчики Prototype решили по-своему ;) Ладно, в одном из их mailing lists я прочел, что добавление exception handler-а отлавливает эту ситуацию:

     onException: function(requesterObj, exceptionObj) {
                  ajaxReq.options.onFailure(null);
     }

Однако, при повторной проверке и это не сработало…

Итак, если для вас это тоже является новостью, то публикую единственное правильное решение, которое отлавливает все проблемы с сервером:

var ajaxReq = new Ajax.Request('Test.jsp', {
      method: 'get',
      onSuccess: function(transport) {        
        alert('OK');               
      },
      onFailure: function(transport) {
        // this gets invoked if the server responds with an error code.
      	alert('failure');
      },
      onException: function(requesterObj, exceptionObj) {
          ajaxReq.options.onFailure(null);
      },              
      on0: function(transport) {
          // this gets invoked if the server is down.
          ajaxReq.options.onFailure(transport);
      }
});    

Отсутствие status-кода для XHR приравнивается к значению 0, что и приводит к callback-у в функцию on0(), которую надо всегда указывать.
Теги:
Хабы:
Всего голосов 9: ↑9 и ↓0+9
Комментарии6

Публикации