Восемь правил работы с формами
Введение
Формы — основа работы с данными в интернете. С их помощью публикуются новости, делаются заказы в интернет-магазинах, пишутся комментарии и ванильные статусы. Казалось бы, учитывая этот факт, работа с формами с технической точки зрения должна быть отшлифована до блеска. В интернете тонны материалов для разработчиков всех уровней. Но каждый день мы сталкиваемся с очередной безблагодатной формой, сделанной «на отвяжись».
На сегодняшний день формы — самый сложный и громоздкий участок любого веб-сайта. Связано это с тем, что через форму обычные пользователи, по сути, общаются с программой. Пока у нас нет толкового искусственного интеллекта, это общение похоже на попытку мамы отвечать на бесконечный поток вопросов ее чада.
Работу с формами можно условно разделить на три этапа:
- Заполнение и отправка формы
- Проверка введенных данных
- Обработка результата
Рассмотрим все этапы по порядку.
Заполнение формы
Наполнить форму данными — задача не только для пользователя. Часто вместе с пользовательскими данными в форме присутствует и техническая информация, например, уникальный идентификатор редактируемой страницы. Но есть кое-что, что должно присутствовать в каждой форме. Первое правило работы с формами — каждая форма должна содержать уникальный одноразовый ключ. Этот ключ должен автоматически создаваться вместе с формой и проверяться при ее получении сервером. Такие ключи должны быть привязаны к сессии пользователя и удаляться вместе с ней. Это необходимо для защиты вашего сайта от XSRF-атак. Исключениями из первого правила являются формы без побочных эффектов (например, фильтр в списке пользователей).

XSRF (от англ. Cross-site request forgery) — вид атаки, при котором вредоносные запросы выполняются от имени пользователя, которому доверяет атакуемый сайт. Простейший пример:
<img src="http://bank.example.com/withdraw?account=Bob&amount=1000000&for=Fred" />
Вместо адреса картинки указан адрес запроса на денежный перевод. У злоумышленника нет прав на осуществление этого запроса, но они есть у владельца банковского счета. Злоумышленнику достаточно вставить эту «картинку» в блог владельца банковского счета, и как только тот загрузит страницу с комментариями, запрос будет выполнен.
Второе правило работы с формами — метод GET используется только для форм без побочных эффектов, для всех остальных форм используйте POST. Это стандарт, тут не нужно думать, нужно просто следовать этому правилу.
Помимо технических данных, в форме следует указывать начальные значения полей. Кажется, с этим все понятно? Как бы не так! Третье правило — начальным значением поля должно быть последнее значение, введенное пользователем. Это значит, что если пользователь допустил ошибку во время заполнения формы, вместе с сообщением об ошибке в форме должны быть те значения, которые там были в момент нажатия пользователем кнопки отправки формы.
Четвертое правило — рядом с любым полем, имеющим ограничения любого рода, должна содержаться информация об этих ограничениях. Больше всего в мире меня раздражает, когда после введения своего тридцатидвухсимвольного пароля и его подтверждения я вижу сообщение про максимальную длину пароля.

Хозяйке на заметку
В современных системах пароли не хранятся в базах данных в чистом виде. Вместо них в базе хранится хэш — набор букв, цифр и символов, сгенерированный на основе пароля с помощью специального алгоритма, без возможности произвести обратную операцию. Результат работы такого алгоритма имеет фиксированную длину, независимо от длины самого пароля, поэтому ограничения на длину пароля на сайтах нужны разве чтоб пользователи не смогли в качестве пароля поставить отрывок из «Войны и Мира». Кстати, по этой же причине сайты не могут просто прислать вам ваш пароль на почту, если вы его забыли.
Проверка введенных данных
Наконец, пользователь заполнил форму и нажал на кнопку отправки формы. В этот момент программа начинает обработку данных. Пятое правило — данные всегда должны проверяться на сервере. Любые данные от любого пользователя. Любые ваши JavaScript-проверки только дополняют и упрощают интерфейс, но их слишком легко обойти. Поэтому сервер должен исходить из предположения, что JavaScript-проверок не существует.

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

Значение следует проверять до тех пор, пока не будет найдена ошибка либо правила для этого значения не закончатся. Это нужно для того, чтобы не выводить рядом сообщения «Поле не может быть пустым» и «Минимальная длина значения — 3 символа».

Если во время проверки данных были найдены ошибки, пользователя следует вернуть на форму и вывести все эти ошибки. Шестое правило — ошибка должна отображаться рядом с полем, к которому она относится. Исключением могут быть только скрытые значения, например одноразовый ключ из первого правила.
Обработка результата
Все данные введены и проверены, можно приступать к их обработке.
Седьмое правило — нельзя менять введенные пользователем данные. Если вас не устраивает, что у него в тексте комментария HTML-теги, напишите ему об этом. А лучше просто экранируйте их при выводе, чтоб они выводились как обычный текст. Очевидное исключение составляют поля, в которых включена специальная разметка текста (например, markdown, вики-разметка или bb-коды) или просто разрешен HTML. В таком случае это должно быть указано рядом с полем вместе со ссылкой на помощь по синтаксису разметки. Также можно позволить себе небольшое форматирование данных, например автоматическая расстановка дефисов, пробелов и скобочек в номере телефона (0671234567 превращается в (067) 123-45-67), но не увлекайтесь.
После того, как данные обработаны и все необходимые операции произведены (например, внесены изменения в статью), наступает время для применения восьмого правила — после обработки формы пользователя необходимо перенаправить. Ни в коем случае нельзя выводить какой-либо результат сразу. Это нужно для того, чтобы избежать проблем с обновлением страницы в браузере. Например, я оставил комментарий к записи в блоге, и после обработки данных мне были показаны все комментарии. Если я сейчас обновлю страницу, мой браузер отправит данные повторно, что приведет к повторному добавлению комментария. В случае перенаправления такого не произойдет.

Еще раз, списком
- Каждая форма должна содержать уникальный одноразовый ключ.
- Метод GET используется только для форм без побочных эффектов, для всех остальных форм используйте POST.
- Начальным значением поля должно быть последнее значение, введенное пользователем.
- Рядом с любым полем, имеющим ограничения любого рода, должна содержаться информация об этих ограничениях.
- Данные всегда должны проверяться на сервере.
- Ошибка должна отображаться рядом с полем, к которому она относится.
- Нельзя менять введенные пользователем данные.
- После обработки формы пользователя необходимо перенаправить.
Сайты для людей
Когда долго работаешь в области веб-разработки, в каждом сайте видишь в первую очередь набор технологий и функций. За всеми этими вещами порой забываешь, что интернет создается людьми для людей и удобен он должен быть, в первую очередь, людям. Именно таким подходом я руководствовался при составлении моих правил. Надеюсь, они помогут вам, и вместе мы сделаем интернет аккуратнее и удобнее для всех.