Справочник · HTML
Тег <form>: собираем и отправляем данные
Тег <form> объединяет поля ввода и описывает, куда и как отправить их значения. Адрес задаёт атрибут action, способ — method (get или post). При отправке браузер собирает пары name=значение из всех полей формы и отправляет их одним запросом.
action— адрес обработчика,method— get или post.- В запрос попадают только поля с атрибутом
name. - Для отправки файлов нужен
enctype="multipart/form-data"и method post. - Формы нельзя вкладывать одна в другую.
- Кнопка в форме по умолчанию отправляет её — для других действий
type="button".
Минимальный пример
<form action="/subscribe" method="post">
<label for="email">Почта</label>
<input id="email" name="email" type="email" required>
<button type="submit">Подписаться</button>
</form>По нажатию кнопки браузер проверит поле, соберёт пару email=… и отправит POST-запрос на /subscribe. Страница перейдёт на ответ сервера. Чтобы остаться на странице и отправить данные в фоне, используют JavaScript и fetch.
Атрибуты тега form
| Атрибут | Значения | Что делает |
|---|---|---|
action | URL | куда отправить; без него — на текущий адрес |
method | get, post, dialog | способ отправки; по умолчанию get |
enctype | application/x-www-form-urlencoded, multipart/form-data, text/plain | как закодировать данные для post |
novalidate | логический | отключить встроенную проверку |
autocomplete | on, off | подсказки браузера для всех полей |
target | _self, _blank | где открыть ответ |
name | строка | имя формы для скриптов |
get и post
<!-- поиск: данные в адресе, результат можно сохранить ссылкой -->
<form action="/search" method="get">
<input name="q" type="search" aria-label="Поиск">
<button>Найти</button>
</form>
<!-- откроется /search?q=flexbox -->При get пары добавляются к адресу после знака вопроса. Это удобно для поиска и фильтров: ссылку можно скопировать и вернуться к результату. При post данные идут в теле запроса и не видны в адресе — так отправляют заявки, регистрацию и всё, что меняет данные. Пароли и личные данные никогда не отправляют через get: они останутся в истории браузера и журналах сервера.
Значение method="dialog" работает внутри <dialog>: отправка формы просто закрывает окно.
Как браузер собирает данные
<form action="/order" method="post">
<input name="name" value="Анна">
<input name="email" value="anna@example.ru">
<input type="checkbox" name="news" value="yes" checked>
<input type="checkbox" name="sms" value="yes"> <!-- не отмечен — не отправится -->
<input value="без имени"> <!-- нет name — не отправится -->
<input name="promo" disabled value="SALE"> <!-- disabled — не отправится -->
<button>Заказать</button>
</form>
<!-- уйдёт: name=Анна&email=anna%40example.ru&news=yes -->В отправку попадают поля с name, кроме отключённых (disabled) и неотмеченных галочек и переключателей. Если нужно отправить значение, которое нельзя менять, используй readonly вместо disabled. Скрытые служебные значения передают через input type="hidden".
Отправка файлов
<form action="/upload" method="post" enctype="multipart/form-data">
<label for="cv">Резюме в PDF</label>
<input id="cv" name="cv" type="file" accept=".pdf">
<button>Отправить</button>
</form>Без enctype="multipart/form-data" сервер получит только имя файла, а не его содержимое. Работает только с методом post. Атрибут accept подсказывает, какие файлы предлагать в окне выбора, но не заменяет проверку на сервере.
Кнопки и отправка
<button type="submit">Отправить</button>
<button type="button">Показать пароль</button>
<button type="submit" formaction="/draft" formnovalidate>Сохранить черновик</button>Кнопка внутри формы по умолчанию имеет type="submit". Вспомогательные кнопки помечай type="button". Атрибуты formaction, formmethod и formnovalidate на кнопке меняют поведение формы только для неё — например, «Сохранить черновик» без проверки обязательных полей. Нажатие Enter в текстовом поле тоже отправляет форму.
Поля вне формы и вложенность
<form id="search-form" action="/search"></form>
…
<input name="q" form="search-form">
<button form="search-form">Найти</button>Форму нельзя вложить в другую форму — браузер проигнорирует внутренний тег form. Если поле по вёрстке оказывается вне формы, его связывают атрибутом form с id нужной формы.
Отправка через JavaScript
const form = document.querySelector('#subscribe');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const response = await fetch(form.action, {
method: 'POST',
body: new FormData(form),
});
form.querySelector('.status').textContent = response.ok ? 'Готово!' : 'Ошибка, попробуйте снова';
});Обработчик вешают на событие submit самой формы, а не на клик по кнопке — тогда сработает и Enter в поле. FormData собирает те же пары, что и браузер. Подробнее — на страницах FormData и Fetch API.
form или div с полями
Отправка по Enter, встроенная проверка, событие submit, подсказки автозаполнения, работа без JavaScript.
Ничего из этого нет: всё придётся писать скриптом, а Enter и проверка работать не будут.
Частые ошибки
- У полей нет
name, и сервер получает пустой запрос. - Вкладывают одну форму в другую.
- Отправляют пароли и личные данные методом get.
- Забывают
enctype="multipart/form-data"при загрузке файлов. - Вешают обработчик на клик по кнопке вместо submit формы.
Доступность
Связывай каждое поле с подписью label, группируй переключатели в fieldset с legend, выводи ошибки текстом рядом с полем. Если форма — главная часть страницы (поиск, вход), дай ей понятное имя через aria-label или заголовок: скринридер покажет её среди областей страницы.
Поддержка браузерами
Тег form и все перечисленные атрибуты работают во всех браузерах. method="dialog" поддерживается всеми актуальными браузерами вместе с тегом dialog.
Практика
Собери форму отклика на вакансию: имя, почта, файл резюме, согласие на обработку данных. Данные отправляются методом post на /apply вместе с файлом. Добавь кнопку «Сохранить черновик», которая отправляет форму на /draft без проверки обязательных полей.
Показать решение
<form action="/apply" method="post" enctype="multipart/form-data">
<label for="a-name">Имя</label>
<input id="a-name" name="name" autocomplete="name" required>
<label for="a-email">Почта</label>
<input id="a-email" name="email" type="email" autocomplete="email" required>
<label for="a-cv">Резюме</label>
<input id="a-cv" name="cv" type="file" accept=".pdf,.doc,.docx" required>
<label><input type="checkbox" name="consent" value="yes" required> Согласен на обработку данных</label>
<button type="submit">Откликнуться</button>
<button type="submit" formaction="/draft" formnovalidate>Сохранить черновик</button>
</form>Частые вопросы
Что будет, если не указать action?
Форма отправится на адрес текущей страницы.
Какой method у формы по умолчанию?
get. Для заявок и регистрации явно указывай method="post".
Почему сервер не получает файл?
У формы нет enctype="multipart/form-data" или метод не post. Без этого отправляется только имя файла.
Почему значение поля не пришло на сервер?
У поля нет name, оно disabled, или это неотмеченная галочка. Для неизменяемого значения используй readonly.
Можно ли вложить форму в форму?
Нет. Браузер проигнорирует внутренний тег form. Поле вне формы связывают с ней атрибутом form.