0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>В этом уроке мы изучим формы, которые меняют данные. И с клиентской, и с серверной стороны они обычно устроены сложнее, чем поисковые формы. Для уверенной работы с ними нужно разбираться:</p>
1
<p>В этом уроке мы изучим формы, которые меняют данные. И с клиентской, и с серверной стороны они обычно устроены сложнее, чем поисковые формы. Для уверенной работы с ними нужно разбираться:</p>
2
<ul><li>Как работают соответствующие HTML-теги</li>
2
<ul><li>Как работают соответствующие HTML-теги</li>
3
<li>Как отправляются формы по HTTP</li>
3
<li>Как отправляются формы по HTTP</li>
4
<li>Как происходит обработка на стороне сервера</li>
4
<li>Как происходит обработка на стороне сервера</li>
5
<li>Как работает валидация и вывод ошибок</li>
5
<li>Как работает валидация и вывод ошибок</li>
6
</ul><p>Все это мы изучим в ближайшее время.</p>
6
</ul><p>Все это мы изучим в ближайшее время.</p>
7
<h2>Вывод формы</h2>
7
<h2>Вывод формы</h2>
8
<p>За вывод формы и ее обработку должны отвечать два разных маршрута - а значит, еще и два обработчика. Рассмотрим примеры маршрутов для создания нового пользователя:</p>
8
<p>За вывод формы и ее обработку должны отвечать два разных маршрута - а значит, еще и два обработчика. Рассмотрим примеры маршрутов для создания нового пользователя:</p>
9
<ul><li>GET<em>/users/build</em>- страница с формой, которую заполняет пользователь. Эта форма отправляет POST-запрос на адрес<em>/users</em>, указанный в атрибуте action</li>
9
<ul><li>GET<em>/users/build</em>- страница с формой, которую заполняет пользователь. Эта форма отправляет POST-запрос на адрес<em>/users</em>, указанный в атрибуте action</li>
10
<li>POST<em>/users</em>- маршрут, обрабатывающий данные формы</li>
10
<li>POST<em>/users</em>- маршрут, обрабатывающий данные формы</li>
11
</ul><p>Для нашей задачи мы будем использовать класс пользователя. Он может выглядеть так:</p>
11
</ul><p>Для нашей задачи мы будем использовать класс пользователя. Он может выглядеть так:</p>
12
<p>Добавим обработчик маршрута<em>/users/build</em>, который выводит форму добавления пользователя:</p>
12
<p>Добавим обработчик маршрута<em>/users/build</em>, который выводит форму добавления пользователя:</p>
13
<p>Создадим форму в файле<em>src/main/jte/users/build.jte</em>:</p>
13
<p>Создадим форму в файле<em>src/main/jte/users/build.jte</em>:</p>
14
<p>Запустим сервер и убедимся, что форма выводится по адресу<em>/users/build</em>. Если ее заполнить и попытаться отправить, то браузер сформирует следующий HTTP-запрос:</p>
14
<p>Запустим сервер и убедимся, что форма выводится по адресу<em>/users/build</em>. Если ее заполнить и попытаться отправить, то браузер сформирует следующий HTTP-запрос:</p>
15
<p>В примере выше мы видели работу с HTTP, но на практике все устроено немного по-другому. Не стоит передавать электронную почту, пароль и другие чувствительные данные по обычному HTTP-протоколу, потому что так данные легко перехватить и использовать не по назначению.</p>
15
<p>В примере выше мы видели работу с HTTP, но на практике все устроено немного по-другому. Не стоит передавать электронную почту, пароль и другие чувствительные данные по обычному HTTP-протоколу, потому что так данные легко перехватить и использовать не по назначению.</p>
16
<p>Именно поэтому современные сайты обычно работают по протоколу HTTPS, который передает данные в зашифрованном виде.</p>
16
<p>Именно поэтому современные сайты обычно работают по протоколу HTTPS, который передает данные в зашифрованном виде.</p>
17
<h2>Обработка данных</h2>
17
<h2>Обработка данных</h2>
18
<p>Форма готова, теперь можно реализовывать ее обработчик. Обработчик формы работает так:</p>
18
<p>Форма готова, теперь можно реализовывать ее обработчик. Обработчик формы работает так:</p>
19
<ul><li>Извлекает параметры формы через метод ctx.formParam()</li>
19
<ul><li>Извлекает параметры формы через метод ctx.formParam()</li>
20
<li>Формирует объект пользователя на основе этих параметров</li>
20
<li>Формирует объект пользователя на основе этих параметров</li>
21
<li>Сохраняет объект пользователя в базу данных</li>
21
<li>Сохраняет объект пользователя в базу данных</li>
22
<li>Выполняет редирект - например, на страницу пользователей</li>
22
<li>Выполняет редирект - например, на страницу пользователей</li>
23
</ul><p>Код обработчика выглядит так:</p>
23
</ul><p>Код обработчика выглядит так:</p>
24
<p>Примерно так выглядит большинство обработчиков форм. Они могут быть сложнее, но общая структура остается похожей: мы извлекаем данные, создаем нужные объекты на основе них и вносим изменения в базу. В конце мы выполняем редирект или формируем необходимый ответ клиенту.</p>
24
<p>Примерно так выглядит большинство обработчиков форм. Они могут быть сложнее, но общая структура остается похожей: мы извлекаем данные, создаем нужные объекты на основе них и вносим изменения в базу. В конце мы выполняем редирект или формируем необходимый ответ клиенту.</p>
25
<h2>Нормализация данных</h2>
25
<h2>Нормализация данных</h2>
26
<p>Представим, что при регистрации пользователь написал свою почту в произвольном регистре -<em><a>MYname@example.com</a></em>вместо<em><a>myname@example.com</a></em>. По спецификации, адреса электронной почты не зависят от регистра. Другими словами, если в двух адресах совпадают буквы, то они считаются одним и тем же адресом.</p>
26
<p>Представим, что при регистрации пользователь написал свою почту в произвольном регистре -<em><a>MYname@example.com</a></em>вместо<em><a>myname@example.com</a></em>. По спецификации, адреса электронной почты не зависят от регистра. Другими словами, если в двух адресах совпадают буквы, то они считаются одним и тем же адресом.</p>
27
<p>Проблема в том, что с точки зрения кода и большинства баз данных мы сравниваем строки с учетом регистра. В итоге наш проект ждут два сюрприза:</p>
27
<p>Проблема в том, что с точки зрения кода и большинства баз данных мы сравниваем строки с учетом регистра. В итоге наш проект ждут два сюрприза:</p>
28
<ul><li>Пользователь сможет зарегистрировать несколько аккаунтов на один и тот же адрес почты, просто вводя адрес в разном регистре</li>
28
<ul><li>Пользователь сможет зарегистрировать несколько аккаунтов на один и тот же адрес почты, просто вводя адрес в разном регистре</li>
29
<li>Пользователь не сможет зайти на сайт, если введет почту не в том регистре, который использовал при регистрации</li>
29
<li>Пользователь не сможет зайти на сайт, если введет почту не в том регистре, который использовал при регистрации</li>
30
</ul><p>Чтобы этого не происходило, введенные пользователями данные проходят<strong>нормализацию</strong>. В случае почты мы приводим ее к нижнему регистру:</p>
30
</ul><p>Чтобы этого не происходило, введенные пользователями данные проходят<strong>нормализацию</strong>. В случае почты мы приводим ее к нижнему регистру:</p>
31
<p>Пользователь может не только ошибиться в регистре, но и случайно поставить пробелы в конце или в начале строк - например, из-за копирования. Иногда мы не можем на это влиять. Например, пользователь может специально добавить пробельный символ в начале и конце пароля.</p>
31
<p>Пользователь может не только ошибиться в регистре, но и случайно поставить пробелы в конце или в начале строк - например, из-за копирования. Иногда мы не можем на это влиять. Например, пользователь может специально добавить пробельный символ в начале и конце пароля.</p>
32
<p>А вот для имени и адреса почты такое недопустимо. Поэтому лучше обрезать концевые пробелы для надежности:</p>
32
<p>А вот для имени и адреса почты такое недопустимо. Поэтому лучше обрезать концевые пробелы для надежности:</p>
33
33