Обработка ошибок HTTP 4nn / 5nn на стороне сервера, возвращающих весь документ HTML в запросах jQuery ajax - PullRequest
19 голосов
/ 15 ноября 2009

Кстати, как бы вы обрабатывали ошибки HTTP 4nn / 5nn на стороне сервера в запросах jQuery ajax? Этот случай касается веб-приложения JSP / Servlet на стороне сервера. Здесь я не говорю о тривиальных исключениях времени выполнения, таких как NullPointerException и так далее. Предположим, что они все обрабатываются отлично. Хорошим примером такой ошибки HTTP 4nn / 5nn является 401 несанкционированный (недостаточно прав пользователя) и внутренняя ошибка 500 сервера (ошибка базы данных, ошибка ввода-вывода, Error s и т. Д.). Предположим, что они не могут (или не должны) быть пойманы на уровне кодирования.

Сейчас я только что объявил <error-page> в web.xml для таких ошибок. По сути, он перенаправляет запрос на заранее определенную страницу ошибок JSP / HTML, на которой конечному пользователю сообщается, что произошла серьезная ошибка и что пользователь может связаться с xx@xx.xx для получения дополнительной помощи. На этой же странице отображаются общие сведения об ошибке / исключении.

Он прекрасно работает в обычных HTTP-запросах, но как бы вы справились с этим в XMLHtttp-запросах с использованием jQuery? Что лучше для пользователя? Для меня это было бы просто отображением всей страницы ошибки, как если бы это был обычный HTTP-запрос. Я решил это следующим образом:

function init() {
    $.ajaxSetup({
        error: handleXhrError
    });
}

function handleXhrError(xhr) {
    document.open();
    document.write(xhr.responseText);
    document.close();
}

Хотя это работает прекрасно, мне кажется, что это взлом. Замена всего документа содержимым страницы ошибок HTTP. Но так ли вы будете следовать? Если нет, то можете ли вы уточнить, почему нет и каким способом вы бы предпочли? Единственная альтернатива, которую я вижу, - использовать JS для отображения некоторого окна предупреждения / сообщения, чтобы проинформировать пользователя о неразрешимой ошибке, но пользователь может отклонить ее и продолжить работу со страницей, пока это не должно быть возможно.

Ответы [ 5 ]

5 голосов
/ 28 марта 2013

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

function handleXhrError(xhr) {
    document.open();
    document.write(xhr.responseText);
    document.close();
}

потерпит неудачу в IE6 / 7/8, когда у вас есть <script> элементы, которые также необходимо загрузить и инициализировать. IE6 / 7/8 именно не будет этого делать. Чтобы заставить IE сделать это, вам нужно сохранить текущий элемент <head> и заменить только его дочерние элементы на $("head").html(newHead). То же самое должно быть сделано для элемента <body>.

function handleXhrError(xhr) {
    var newDocument = xhr.responseText;
    $("head").html(newDocument.substring(newDocument.indexOf("<head>") + 6, newDocument.indexOf("</head>")));
    $("body").html(newDocument.substring(newDocument.indexOf("<body>") + 6, newDocument.indexOf("</body>")));
}

Неприятно, но невозможно сделать $(xhr.responseText), когда текст ответа представляет собой целый HTML-документ с заголовком и телом. Не забудьте соответствующим образом изменить индекс подстроки, если у вас есть некоторые атрибуты в <body> шаблона страницы ошибки (например, ID, класс и т. Д.).

3 голосов
/ 16 ноября 2009

Используйте диалог JQuery, что-то вроде этого:

function handleXhrError(xhr) {
   ele = $("<div></div>").appendTo("body");
   ele.html(xhr.responseText);
   $(ele).dialog();

}

Я должен ответить на все остальное, что вы спросили. Я бросаю и ловлю определенные исключения, где могу, и отправляю специальные сообщения клиенту. Иногда я приказываю клиенту запустить функцию, которая может перенаправить браузер или частично обновить часть страницы. Это зависит только от обстоятельств. Catching 400/500 будет иметь дело с реальными ошибками, но вы также хотите написать JS-код один раз, чтобы отфильтровать все ваши AJAX-запросы для пользовательских флагов ошибок, которые вы вернете с сервера, посмотрите на эту страницу, чтобы узнать больше: http://www.bennadel.com/blog/1392-Handling-AJAX-Errors-With-jQuery.htm

2 голосов
/ 16 ноября 2009

При необходимости вы также сможете перенаправить на одну из предопределенных страниц ошибок, которые вы создали с помощью window.location.href = "url-to-error-page";

1 голос
/ 13 декабря 2009

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

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

Теория, лежащая в основе этого, связана с транзакциями. Обычно поток выполнения:

  1. Поручить менеджеру транзакций начать транзакцию
    1. Начать транзакцию
    2. Состояние захвата
    3. Вернуть управление на код вызова
  2. Начать операции, являющиеся частью транзакции
  3. При ошибке: дать указание менеджеру транзакций откатить транзакцию.
    1. Вернуть среду выполнения в состояние, указанное выше
    2. Отменить любые данные, которые больше не нужны (например, сериализация состояния)
  4. В случае успеха: дать указание менеджеру транзакции зафиксировать транзакцию.
    1. Завершение операций в транзакции по мере необходимости
    2. Отменить любые данные, которые больше не нужны

Я не провел серьезного исследования по управлению транзакциями в javascript. Поскольку вы заявляете, что ошибка на стороне сервера делает клиентскую часть непригодной для использования, возможно, есть какой-то способ реализовать части транзакции на стороне сервера. Важно, чтобы вы не оставляли вещи наполовину выполненными там больше, чем на стороне клиента.

Задумывались ли вы о том, чтобы выполнить запрос «предполетной проверки», чтобы попытаться выявить эти проблемы до того, как клиентское приложение попытается выполнить реальную работу?

1 голос
/ 03 декабря 2009

Я думаю, что лучше дать короткое сообщение вместо того, чтобы полностью переписать вашу страницу. Таким образом, это не будет сильно мешать самой странице. Google Reader и Gmail делают что-то вроде этого. Читатель показывает сообщение и не помечает прочитанные вами записи, но вы все равно можете прочитать все загруженные сообщения.

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