Как сделать форму в HTML
Форма это элемент <form> с полями и кнопкой отправки. Каждому полю нужен name: это ключ, под которым отправляется значение. Заполните форму и нажмите Send. Превью никуда ничего не отправляет; оно показывает ровно то, что отправил бы браузер.
Из чего она состоит:
actionэто URL, куда уходят данные, аmethodзадает способ (здесьpost).nameу каждого поля. Его значение это то, что ввел читатель.<label>называет каждое поле на экране и для программ чтения с экрана (см. label в HTML).requiredиtype="email"заставляют браузер проверить поля перед отправкой. Попробуйте отправить форму с пустым именем или сabcв качестве email.- Кнопка отправки отправляет форму. Нажатие Enter в текстовом поле тоже.
action и method: куда и как уходят данные
| Атрибут | Значения | По умолчанию |
|---|---|---|
action | Любой URL | URL текущей страницы |
method | get, post, dialog | get |
enctype | application/x-www-form-urlencoded, multipart/form-data, text/plain | application/x-www-form-urlencoded |
С method="get" поля становятся строкой запроса в URL: форма поиска с name="q" переходит на /search?q=blue+shoes. Это правильно для поиска и фильтров, потому что результат можно сохранить в закладки и отправить другим. С method="post" поля уходят в теле запроса и не появляются ни в адресной строке, ни в истории. Используйте POST для всего, что выполняет вход, создает, изменяет или удаляет что-либо, а также для паролей.
Форме с загрузкой файла (<input type="file">) нужны method="post" и enctype="multipart/form-data", иначе отправится только имя файла. method="dialog" нужен для формы внутри <dialog>: отправка закрывает диалог, а не отправляет запрос.
Что отправляется
Отправляются только поля с name, и только если они не disabled. Нажмите Submit и сравните поля с тем, что отправляет форма:
Форма отправляет city, zip, source и action. Поле без имени, отключенное поле и неотмеченный чекбокс пропускаются. Скрытые поля отправляются, но никогда не показываются, а кнопка отправки передает собственные name и value, потому что форму отправили именно ею.
Группировка полей через fieldset и legend
<fieldset> рисует рамку вокруг связанных полей, а <legend> это ее подпись. Программы чтения с экрана объявляют legend, когда фокус входит в группу, и именно это делает понятным набор радиокнопок вроде приведенного ниже: «Delivery, Standard, радиокнопка».
disabled у fieldset сразу отключает все поля внутри, и ни одно из них не отправляется. Уберите его, и поля для подарка станут доступны.
Встроенная валидация: required, pattern и другие
Браузеры проверяют эти атрибуты перед отправкой и показывают сообщение у первого поля, не прошедшего проверку:
| Атрибут | Что проверяет |
|---|---|
required | Поле не пустое (чекбокс отмечен) |
type="email", type="url" | Значение похоже на адрес email или URL |
minlength, maxlength | Длину текста |
min, max, step | Диапазон чисел и дат |
pattern | Все значение соответствует регулярному выражению |
:invalid и :valid оформляют поля по их состоянию. Обычно лучше :user-invalid: он срабатывает только после того, как читатель изменил поле и перешел дальше или попытался отправить форму, поэтому пустая форма не открывается вся в красном.
С pattern часто путаются в трех вещах. Он должен совпадать со всем значением (^ и $ не нужны). Он проверяется, только когда поле не пустое, поэтому используйте его вместе с required. А сообщение браузера об ошибке общее, поэтому опишите формат видимым текстом рядом с полем. Chrome и Firefox добавляют к своему сообщению текст title, но его легко не заметить.
Чтобы отключить проверки, например пока вы тестируете валидацию на сервере, добавьте <form> атрибут novalidate. Отдельная кнопка отправки может пропускать их через formnovalidate.
Валидация в браузере нужна для удобства читателя. Любой может изменить страницу или отправить запрос в обход нее, поэтому сервер обязан снова проверять каждое значение.
Свои сообщения через setCustomValidity
Когда правило нельзя записать атрибутом, например «оба пароля должны совпадать», задайте сообщение из JavaScript. Поле с непустым собственным сообщением считается некорректным; пустая строка снова делает его корректным:
У поля повтора нет name, поэтому отправляется только одна копия пароля.
Обработка отправки в JavaScript
Чтобы отправить форму, не уходя со страницы, слушайте submit, вызовите preventDefault() и прочитайте поля через FormData. Событие submit, в отличие от click у кнопки, ловит все способы отправки, включая Enter, и срабатывает только после успешной встроенной валидации:
Object.fromEntries(new FormData(form)) превращает поля в обычный объект. Для полей, у которых может быть несколько значений (чекбоксы с общим именем, select с множественным выбором), используйте formData.getAll('name'), потому что объект сохраняет только последнее значение.
Частые ошибки
- Поля без
name. Их молча не включают в отправляемые данные. - Placeholder вместо label. Подсказка исчезает, как только читатель начинает печатать. Используйте
<label>. <button>безtype, который нужен не для отправки. Внутри формы это кнопка отправки.- Форма внутри формы. Вложенные формы некорректны; браузер игнорирует внутренний тег
<form>. - Обработчик
clickу кнопки отправки вместоsubmitу формы. Отправка по Enter теряется. - Доверие браузерной валидации на стороне сервера. Проверяйте данные там еще раз.
- GET для паролей. Они попадают в URL, историю и журналы сервера.
Часто задаваемые вопросы
Как сделать форму в HTML?
Оберните поля в <form action="/signup" method="post">, дайте каждому полю name и <label> и закончите кнопкой <button type="submit">. При отправке формы браузер передает каждую пару name=value по URL из action.
Чем отличаются GET и POST в форме?
method="get" (по умолчанию) помещает поля в URL, как в /search?q=shoes: это подходит для поиска и фильтров, которые стоит сохранять в закладки. method="post" отправляет их в теле запроса, и это то, что нужно для входа, регистрации и всего, что меняет данные.
Почему поле формы не отправляется?
У него нет атрибута name, или оно disabled. Отправляются только поля с именем, которые не отключены. Неотмеченный чекбокс или радиокнопка тоже полностью пропускаются.
Для чего нужны fieldset и legend?
<fieldset> группирует связанные поля, а <legend> это подпись группы. Программы чтения с экрана объявляют legend, когда фокус входит в группу, и именно это делает группу радиокнопок понятной, а disabled у fieldset отключает все поля внутри.
Как проверить форму в HTML без JavaScript?
Используйте атрибуты: required, type="email", minlength, maxlength, min, max и pattern. Браузер блокирует отправку и показывает сообщение у первого некорректного поля. Всегда проверяйте данные и на сервере, потому что эти проверки выполняются в браузере читателя и их можно обойти.
Как отправить форму без перезагрузки страницы?
Слушайте событие формы submit и вызовите event.preventDefault(), а затем отправьте данные сами через fetch: form.addEventListener('submit', (e) => { e.preventDefault(); fetch(form.action, { method: 'POST', body: new FormData(form) }); }).