Всем нравятся приложения, использующие Ajax, когда они хорошо работают. А если что-то идет не так?

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

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

Когда хорошие приложения ведут себя плохо.

Ajax очень удобен тем, что исключает необходимость перезагрузки страницы, но это может быть опасно, потому что в таком случае браузер не может обработать ошибки. Обычное сообщение «Server Not Found» упрощает жизнь, пользователю внося ясность, что дальше нужно нажать кнопку «Назад». Если Ajax не дает браузеру возможности обрабатывать ошибки значит, это должны сделать мы.

Подготовьте запасной план

Главное правило создания клиентских скриптов, не забывать о пользователях, у которых они отключены. В случае использования Ajax это сделать довольно просто с помощью использования «захвата» (или «hijaxing») ссылки или формы.

<form action="traditional_action.php" method="post"
    onsubmit="perform_ajax_action(); return false;">

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

Мы можем пойти дальше и проверить поддерживает ли браузер объект XMLHttpRequest. Вместо использования явного вызова return false в обработчике onsubmit, мы можем проверить есть ли необходимые для Ajax объекты, в вызываемой функции, и выполнить код Ajax если он поддерживается или передать управление форме если нет. Проверим, существует ли функция createAjaxRequest создающая соответствующий браузеру объект XMLHttpRequest.

var request; // our request object

function perform_ajax_action(){
    if (!request = createAjaxRequest()) {
        // попытка использовать Ajax не удалась,
        //подтверждаем форму
        return true; 
    }

    // нормальная обработка с помощью Ajax
    //...
    return false; // не подтверждать форму
}

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

<form action="traditional_action.php" method="post"
    onsubmit="return perform_ajax_action();">

Если все пройдет хорошо, будет выполнен код Ajax, а подтверждение формы пропущено. При наличии проблем с поддержкой Ajax, форма будет подтверждена, и пользователь сможет продолжить работу обычным образом.

Информируйте пользователя

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

О каких ошибках мы должны сообщить пользователю? Для начала это ошибки соединения. Если запрос не удался, мы сможем получить код ошибки с помощью XMLHttpRequest и вывести соответствующее сообщение. Здесь приведен отрывок функции, которая обрабатывает событие onreadystatechange, объекта request класса XMLHttpRequest.

if (request.readyState == 4) {  // 4(complete) запрос выполнен
    if (request.status == 200) {
        // HTTP OK, продолжаем нормальную обработку Ajax
        //...
    } else {
        // что-то пошло нетак, сообщаем об ошибке
        error("HTTP " + request.status + ". Произошла ошибка: " + request.statusText); 
    }
}

Следующий тип ошибок, который мы должны рассмотреть это ошибки уровня приложения. Эти ошибки происходят, если что-то пошло не так с вашим приложением, и способы, которыми можно обрабатывать эти ошибки, индивидуальны, но все же рассмотрим базовые принципы.

Цикл не должен прерываться

Очень важно, чтобы цикл связи Ajax не прерывался. Серверный скрипт должен в любом случае возвращать корректный XML документ, иначе браузер (и пользователь) останутся в недоумении, без малейшего намека на природу ошибки. Если серверный скрипт завершится аварийно, сообщение об ошибке будет утеряно и приложение тихо упадет. Поэтому очень важно проверять исходные данные, чтобы обезопасить приложение. Посмотрите на это пример, здесь проверяется, не произошло ли ошибок при открытии файла.

if (!$fp = fopen($filename, 'r')) {
    $error_msg = 'Невозможно открыть файл' . $filename;
    exit();
} else {
    // нормальная обработка
    //...
}

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

Передача ошибок

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

В этом примере, используется элемент success, который содержит 1, если ошибок не произошло и −1, если они имеют место. Также используется элемент error, который содержит описание ошибки. Клиентский скрипт проверяет наличие ошибок и отображает соответствующее сообщение, чтобы пользователь знал, что произошло.

Настоящий убийца Ajax: тихие ошибки.

А что делать с тихими ошибками, такими как таймауты и потерянные пакеты? Если веб приложение загадочно перестает работать, пользователь начинает терять терпение, нажимать «Обновить» или «Назад». Это не лучшая ситуация, пользователь может вернуться на несколько шагов, если приложение разработано хорошо, никакая информации не должна быть потеряна, вам нужно постоянно сохранять данные на сервере. Но для пользователя будет созданы дополнительные неудобства, ему придется начинать работу заново.

Как это предотвратить? Информируйте пользователя. Сообщайте ему, сколько времени осталось до выполнения запроса. Если прошло больше времени, чем необходимо, выводите предупреждение, сообщите о том что, возможно, произошла ошибка, и предоставьте несколько вариантов поведения на выбор: подождать еще немного или перезагрузить страницу. Это простой, но эффективной способ предупреждения об ошибках, который повысит уверенность пользователей в надежности вашего приложения.

Второй пример показывает эту идею в действии, если серверный скрипт задерживает ответ больше чем на 30 секунд, пользователю сообщается об этом, и предлагаются варианты действий. Попробуйте изменить время задержки, чтобы увидеть, как это выглядит. Представьте, что вы используете dial-ap с плохим качеством связи. Вы будете очень признательны приложению, которое беспокоится о вашей информированности.

Это только начало

Это ни в коем случае не исчерпывающее руководство по обработке ошибок в Ajax. Есть много различных способов использования Ajax, чтобы сделать приложение более качественным, и конечно на этом пути может возникнуть множество проблем и придется найти множество решений. Чем более изящно и полно обрабатываются ошибки, тем больше доверия внушает ваше приложение.

Исходные файлы примеров с AJAX, включая серверные скрипты в архиве

Translated with the permission of A List Apart Magazine and the author[s].

Похожие статьи