HTML-форма и отправка параметров
Разберём устройство HTML-формы: подписи, имена полей, проверку заполнения и передачу параметров.
Каталог уже показывает курсы и ведёт к их оглавлениям. Ниже добавим учебную заявку. Она не оформляет подписку и не сохраняет данные: после отправки браузер откроет соседнюю статическую страницу, а значения будут видны в адресной строке. Такая ограниченная задача позволяет отдельно увидеть работу HTML-формы, не смешивая её с сервером, письмами и обработчиками JavaScript.
Используйте вымышленное имя. Для примера достаточно двух параметров: reader и course. Мы не добавляем email, согласия и другие поля настоящего сбора данных. Их появление изменило бы назначение интерфейса и потребовало бы обсуждения обработки заявки. Здесь результатом является понимание того, какие значения браузер передаёт и откуда берутся их имена.
Подпись, поле и отправка
Замените прежний абзац с id="request" следующим разделом. В полном снимке список вариантов содержит все шесть курсов; здесь оставлены два для разбора структуры:
<section class="lab-request" id="request" aria-labelledby="request-title">
<h2 id="request-title">Учебная заявка</h2>
<p>Форма показывает отправку параметров. Подписка и хранение данных не выполняются.</p>
<form action="receipt.html" method="get">
<p>
<label for="reader">Имя для примера</label>
<input id="reader" name="reader" autocomplete="off" required maxlength="60">
</p>
<p>
<label for="course">Курс</label>
<select id="course" name="course">
<option value="markdown">Статический сайт из Markdown</option>
<option value="seo">Техническое SEO</option>
</select>
</p>
<button type="submit">Показать параметры</button>
</form>
</section>
Подпись связывается с полем через совпадение for и id. Она объясняет, что ввести, и обычно позволяет выбрать поле нажатием на текст. name решает другую задачу: задаёт имя передаваемого параметра. Если удалить name, поле останется видимым и может принимать ввод, но его значение не попадёт в обычный набор данных формы. Не следует считать id заменой имени параметра.
В option видимый текст предназначен человеку, а value — передаваемое значение. Короткие стабильные значения удобнее длинных названий: название курса можно уточнить, не меняя код параметра. Такое разделение встречается и в серверных формах. Здесь никакой сервер не проверяет значения, но принцип уже виден в адресе после отправки.
Куда попадают параметры
Создайте рядом полный файл receipt.html:
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Параметры учебной заявки</title>
</head>
<body>
<h1>Учебная заявка</h1>
<p>Посмотрите параметры reader и course в адресной строке.
Эта статическая страница не читает их и не сохраняет заявку.</p>
<p><a href="index.html#request">Вернуться к форме</a></p>
</body>
</html>
Если ввести Anna и выбрать Markdown, ожидаемый адрес закончится примерно так:
receipt.html?reader=Anna&course=markdown
Значения не появляются сами в тексте receipt.html: статический документ их не разбирает. Для чтения параметров понадобился бы отдельный код на клиенте или сервере. Сейчас адрес служит наблюдаемым результатом отправки. Атрибуты action, method и устройство формы описаны в MDN.
Метод GET добавляет данные в запрос адреса. В локальном примере браузер открывает файл с query string; при размещении на веб-сервере был бы отправлен HTTP-запрос. Эти условия следует различать: открытие соседнего файла не доказывает работу серверного обработчика. В обоих случаях наше содержимое остаётся статическим и не обещает регистрацию пользователя.
С пробелами, кириллицей и специальными знаками адрес может выглядеть иначе: браузер кодирует значения. Это не порча текста, а способ представить данные в URL. Не нужно вручную заменять пробелы в поле на знаки процента. Форма выполняет сериализацию сама. Для первого наблюдения удобны короткие латинские значения, затем можно сравнить их с вымышленным русским именем.
Встроенная проверка имеет границы
Атрибут required запрещает обычную отправку пустого поля. Попробуйте выбрать кнопку, оставив имя пустым. Ожидается, что браузер покажет своё сообщение и не выполнит переход. Текст сообщения и оформление отличаются между браузерами и языками системы. Мы не будем выдавать конкретную фразу за универсальный результат. Важно условие: пустое обязательное поле не проходит интерактивную проверку.
maxlength ограничивает длину вводимого текста. Это полезное правило интерфейса, но не защита серверной системы. Пользователь способен отправить произвольный запрос другим способом; если обработчик появится, он обязан проверять данные независимо от атрибутов HTML. Сейчас обработчика нет, поэтому мы изучаем только клиентское поведение, не объявляя учебную форму безопасной системой приёма заявок.
Внутри формы кнопка имеет явный type="submit". Если позднее рядом появится кнопка предварительного просмотра, ей потребуется type="button", иначе она тоже может отправить форму. Явное указание помогает читать назначение элемента. Ссылка «Вернуться» в другом документе, наоборот, остаётся ссылкой: она выбирает адрес и не отправляет значения текущих полей.
Группа данных и размещение
Каждое поле находится в своём абзаце с подписью. Пока браузер использует обычное оформление. Указанная структура не гарантирует, что подпись будет над полем: это настроим в уроке о состояниях и стилях элементов управления. Сначала важны связь, имя и порядок. Можно убрать все CSS-правила, а заполнение и передача параметров всё равно должны оставаться понятными.
Не используйте placeholder вместо единственной подписи. После ввода он исчезает и не выражает постоянную связь так же ясно. Если понадобится пример значения, его можно добавить как дополнительную подсказку. Подробное оформление ошибок рассматривается в серии о доступности; здесь у нас лишь встроенная проверка одного обязательного поля.
Для самостоятельной работы добавьте третий вариант курса с value="search" и сравните адрес после выбора. Затем временно удалите name у поля имени. Ожидается, что значение курса останется в адресе, а имя исчезнет. Верните атрибут после наблюдения. Так вы отделите видимость поля, его идентификатор и участие в отправке.
Обратите внимание на отличие пустого значения от отсутствующего параметра. Если необязательное текстовое поле имеет имя, оно может отправить пустую строку. Если имя отсутствует, значение обычно вообще не участвует в наборе. Серверная обработка затем должна различать эти случаи по своему контракту. В нашем опыте эту разницу можно увидеть в адресной строке, не выдумывая ответ настоящего сервера.
Отключённое поле также не следует использовать как надёжное скрытое хранилище для передачи данных. У disabled есть влияние и на взаимодействие, и на участие управления в отправке. Если пользователь не должен менять значение, решение зависит от типа элемента и задачи. Не добавляйте ограничения автоматически ради серого оформления: визуальный стиль можно изменить CSS, а атрибут изменит поведение формы.
Не следует считать query string скрытым каналом. В этом методе значения видны в адресе и могут сохраняться в истории браузера. Поэтому учебный опыт использует вымышленное имя и не собирает секреты. Это не запрет метода GET: он уместен для запросов, параметры которых должны выражать адресуемое состояние. Настоящая заявка с сохранением данных потребовала бы другого серверного контракта и отдельного обсуждения, а не простой замены слова в атрибуте.
Если файл результата отсутствует, отправка может произойти, но открытие цели завершится ошибкой. Такой результат говорит об адресе назначения, а не обязательно о проверке поля. Сравнивайте переход и доступность документа отдельно.
К этому шагу HTML уже содержит каталог, ссылки, обложки и форму. В следующем уроке начнём оформление и разберём, почему браузер выбирает одно CSS-значение среди нескольких подходящих правил, а некоторые свойства получают значение от родителя.