Xpoint
   [напомнить пароль]

Обработка ошибочного заполнения формы

В случае ошибочного заполнения пользователем формы на веб странице, хорошим тоном считается показать ему эту же форму, заполненною введёнными данными (чтобы пользователю не пришлось перенабирать всё заново) и снабжённую сообщением об ошибке.

Чаще всего разработчики идут по пути наименьшего сопротивления, и выводят заполненную форму непосредственно после обработки запроса, т.е. в ответ на POST-обращение к серверу. Это очень просто, т.к. форму выводит тот же скрипт, что и получил данные, данные доступны скрипту «напрямую», и что именно в них неправильно — тоже известно. Однако у такого подхода есть очень серьёзные недостатки, свойственные всем страницам, выдаваемым в ответ на POST. Во-первых, если пользователь нажмёт на такой странице Refresh, то браузер выведет сообщение о том, что страницу обновить невозможно без повторной отсылки данных. Во-вторых, если пользователь правильно заполнил форму во второй раз, и ушёл на другую страницу, то при нажатии на кнопку Back (т.е. при попытке вернуться на POST-страницу) ему опять выведется сообщение о необходимости повторной отсылки данных. Мало того, что это совершенно нелогично и неудобно с точки зрения пользователя (он ведь уже отправил данные!), так ещё и если он в этот момент нажмёт “OK”, то форма и в самом деле запостится во второй раз. Наконец, чтобы не дублировать код, отображающий форму, и сама форма и её обработчик при таком методе обязаны быть реализованы в одном скрипте.

Таким образом, «лобовое» решение влечёт за собой массу проблем как с точки зрения юзабилити, так и с точки зрения структуры приложения.

Проблем этих можно избежать, если после обработки POST-запроса сразу же делать GET-редирект. Если форма заполнена правильно, то редирект делается на нужный адрес, а если неправильно — то обратно на страницу с формой. При этом ошибочно введённые данные передаются через механизм сессий.

Алгоритм обработки формы выглядит следующим образом:

  1. Обработчик получает данные от пользователя и проверяет их на корректность
  2. Если всё правильно, то данные обрабатываются и делается редирект на другую страницу сайта (согласно общей логике системы)
  3. Если в данных есть ошибки, то запускается сессия, и в сессионные переменные записывается следующая информация:
    • Имя (идентификатор) формы. Например, “login_form”. Желательно, хотя и не обязательно (об этом чуть ниже), чтобы имя было уникальным в пределах сайта;
    • Все введённые пользователем данные (напр., в виде ассоциативного массива «имя поля» => «значение»);
    • Перечень полей формы, в которых есть ошибки;
    • Словесное описание ошибки.
  4. Делается редирект обратно на страницу с формой.

Страница, показывающая форму с неким именем (ту же “login_form”), должна сделать следующее:

  1. Если в сессионных переменных нет данных по форме с нужным именем, то пользователю выдаётся чистая (или заполненная значениями по умолчанию) форма.
  2. Если в сессионных переменных есть данные по форме с нужным именем, то пользователю выдаются:
    • Словесное описание ошибки;
    • Форма с полями, заполненными введёнными пользователем данными и, возможно, с выделенными ошибочными полями.
  3. После вывода формы с ошибкой вся информация о ней в сессии стирается.

Последний пункт нужен для того, чтобы не возникло нежелательных взаимодействий между разными формами на сайте с одинаковыми именами (поддерживать строгую уникальность имён довольно трудоёмко) и чтобы не возникло эффекта «залипшей» формы — когда при каждом заходе форма будет показывать ошибочно введённые значения. На самом деле, их достаточно показать ровно один раз — сразу после заполнения формы. После этого информация о данном заполнении формы уже не нужна и её можно и нужно удалить. Таким образом, сессия как таковая живёт очень короткое время — между POST-запросом и выводом формы с ошибкой. При таком подходе уникальность имён не обязательна, поскольку «пересечься» формы могут только если нажать кнопку Submit одновременно в двух открытых окнах с одной и той же страницей.

Вопрос обсуждался здесь:

Powered by POEM™ Engine Copyright © 2002-2005