Работая над проектом, наш разработчик столкнулся с одной особенностью Prototype, проявляющейся при обработке ошибок Ajax-запросов:
Взгляните на следующий код (используется Prototype 1.6.0.3):
Вроде бы банальнее некуда, при успешном запросе получаем «ОК», а если сервер выплюнет 404, 500 или что-то вроде этого, тогда «Failure». Все как положено. Однако, угадайте, как поведет себя этот код, если сервер недоступен (грохнулся, например)?
В моем случае, если я прибиваю Tomcat, то этот код выдает…«ОК»! Сразу справедливый вопрос – WTF?
Поиск по докам Prototype дает следующее:
Лично для меня такого рода guidelines оказались небольшим сюрпризом. Просмотр HTTP spec показал, что вообще-то status code всегда должен быть и его отсутствие не есть ОК, но возможно разработчики Prototype решили по-своему ;) Ладно, в одном из их mailing lists я прочел, что добавление exception handler-а отлавливает эту ситуацию:
Однако, при повторной проверке и это не сработало…
Итак, если для вас это тоже является новостью, то публикую единственное правильное решение, которое отлавливает все проблемы с сервером:
Отсутствие status-кода для XHR приравнивается к значению 0, что и приводит к callback-у в функцию on0(), которую надо всегда указывать.
Взгляните на следующий код (используется 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(), которую надо всегда указывать.