Руководство по HTML5
Адам Фриман
Настройка формы
Мы создали HTML документ, который содержит простую форму, и мы использовали Node.js для отображения данных, которые отправляются на сервер. Теперь пришло время показать вам основные настройки, которые можно применить к форме и ее содержанию.
Настройка формы при помощи атрибута action
Атрибут action
определяет, куда браузер должен отправить данные, полученные от пользователя после отправки формы. Я хочу, чтобы данные были отправлены на мой Node.js скрипт, то есть, я хочу, чтобы форма была отправлена на URL /form
по порту 8080 моего сервера titan. Вы видите, что я уже отобразил это в форме в листинге 12-1 вот таким образом:
...
<form method="post" action="http://titan:8080/form">
...
Если вы не применяете атрибут action
для элемента form
, браузер будет отправлять данные формы на тот же URL, по которому был загружен документ HTML. Это не так бесполезно, как может показаться на первый взгляд, и некоторые популярные фреймворки для веб разработки зависят от этой функции.
Если указать относительный URL, то это значение добавится к URL текущей страницы, или если вы используете элемент base
, описанный в главе 7, то к значению атрибута href
этого элемента. В листинге 12-3 показано, как можно использовать элемент base
при установке точки назначения для данных из формы.
Листинг 12-3: Использование элемента base
при установке точки назначения для данных из формы
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<meta name="author" content="Adam Freeman" />
<meta name="description" content="A simple example" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<base href="http://titan:8080" />
</head>
<body>
<form method="post" action="/form">
<input name="fave" />
<button>Submit Vote</button>
</form>
</body>
</html>
Внимание
Элемент
base
влияет на все относительные URL в HTML документе, а не только на элементform
.
Использование HTTP атрибута method
Атрибут method
определяет, какой HTTP метод будет использоваться для отправки данных формы на сервер. Допустимыми значениями являются get
и post
, которые соответствуют HTTP методам GET
и POST
. Если не применяется атрибут method
, то по умолчанию используется get
, что является не совсем неудачным решением, так как большинство форм требуют HTTP POST
. Вы видите, что в данном примере я указал значение post
для элемента form
вот таким образом:
...
<form method="post" action="http://titan:8080/form">
...
GET
запросы используются для безопасного взаимодействия, то есть вы можете сделать один и тот же запрос столько раз, сколько вы хотите, и не будет никаких изменений на сервере. POST
запросы нужны для небезопасного взаимодействия, когда предоставление данных меняет состояние данных на сервере. Это очень частый случай при работе с веб приложениями. Эти соглашения устанавливаются World Wide Web Consortium (W3C), всю информацию вы можете найти на www.w3.org/Provider/Style/URI.
По негласному правилу GET
запросы должны быть использованы для получения информации «только для чтения» (read-only), в то время как POST
запросы должны быть использованы для любой операции, которая меняет состояние приложения. Для нас очень важно выбрать правильный вид запроса. Если вы в чем-то не уверены, советую использовать метод POST
.
Совет
Скрипт Node.js, который я использую в этой главе, будет отвечать только на
POST
запросы.
Настройка кодирования данных
Атрибут enctype
определяет, как браузер кодирует и представляет данные на сервер. Есть три допустимых значения для данного атрибута, которые описаны в таблице 12-5.
Таблица 12-5: Допустимые значения атрибута enctype
Значение | Описание |
application/x-www-form-urlencoded |
Это кодировка по умолчанию, которая используется, если вы не применяете атрибут enctype . Данная кодировка не может быть использована для загрузки файлов на сервер |
multipart/form-data |
Эта кодировка используется для загрузки данных на сервер |
text/plain |
Эта кодировка колеблется между браузерами. См. следующий текст для более подробной информации |
Чтобы понять, как работают разные кодировки, необходимо добавить в форму второй элемент input
, как показано в листинге 12-4.
Листинг 12-4: Добавление в форму элемента input
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<meta name="author" content="Adam Freeman" />
<meta name="description" content="A simple example" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
</head>
<body>
<form method="post" action="http://titan:8080/form">
<input name="fave" />
<input name="name" />
<button>Submit Vote</button>
</form>
</body>
</html>
Нам нужен второй элемент input
, чтобы собрать две единицы данных от пользователя. Как вы уже догадались, мы создаем форму, которая позволит пользователям голосовать за свои любимые фрукты. Новый элемент input
будет использоваться для сбора их имен. Из этого листинга видно, что я поставил значение name
этого элемента на name
. Чтобы продемонстрировать результат использования различных кодировок, я добавил в форму атрибут enctype
и установил для него каждый из поддерживаемых типов кодировки. Во всех случаях я добавил одни и те же данные в текстовые поля. В первое текстовое поле я ввел Apples
, а во втором я написал Adam Freeman
(с пробелом между именем и фамилией).
Кодировка application/x-www-form-urlencoded
Для кодировки это значение по умолчанию, и оно подходит для всех видов форм, кроме тех, которые загружают файлы на сервер. Имя и значение каждого элемента данных кодируется с помощью той же схемы, которая используется для кодирования URL (следовательно, urlencoded
– это часть названия). Вот таким образом кодирование применяется к данным из примера:
fave=Apples&name=Adam+Freeman
Специальные символы заменяются их HTML аналогами. Имя единицы данных и значение разделяются знаком равенства (=
), а связки данные/значения разделены амперсандом (&
).
Кодировка multipart/form-data
В кодировке multipart/form-data
используется другой подход. Эта кодировка более подробна и сложна в обработке, и именно поэтому она, как правило, используется только для форм, которым нужно загрузить файлы на сервер, а этого нельзя сделать при помощи кодировки по умолчанию. Вот как кодируются данные из формы нашего примера:
------WebKitFormBoundary2qgCsuH4ohZ5eObF
Content-Disposition: form-data; name="fave"
Apples
------WebKitFormBoundary2qgCsuH4ohZ5eObF
Content-Disposition: form-data; name="name"
Adam Freeman
------WebKitFormBoundary2qgCsuH4ohZ5eObF--
fave=Apple
name=Adam Freeman
Кодировка text/plain
Эта кодировка должна использоваться с осторожностью. Нет никакой официальной спецификации о том, как должны быть закодированы данные при использовании этой схемы. Основные браузеры кодируют данные по-разному. Например, Google Chrome кодирует данные таким же образом, как и с применением схемы application/x-www-form-urlencoded
, в то время как Firefox кодирует данные следующим образом:
fave=Apple
name=Adam Freeman
Каждый элемент данных размещается на одной строке, а специальные символы не кодируются. Я рекомендую избегать этой кодировки. Различия между браузерами делают ее непредсказуемой
Управление заполнением формы
Браузеры помогают пользователю тем, что запоминают данные, которые пользователь ввел в форму, и предлагают повторно использовать эти данные автоматически, когда встречается аналогичная форма. Этот метод снижает для пользователя необходимость вводить одни и те же данные снова и снова. Хорошим примером этого могут служить имя и реквизиты, которые пользователь вводит при покупке товаров или услуг в Интернете. Каждый веб сайт имеет свою собственную корзину и процесс регистрации, но вот мой браузер использует данные, которые я вводил в других формах, чтобы ускорить этот процесс. Браузеры используют различные методы, чтобы выяснить, какие данные можно ввести повторно, но общий подход заключается в поиске атрибута name
элементов input
.
В общем, автоматическое заполнение форм является для пользователей полезным и мало что меняет в веб приложении. Но бывают моменты, когда мы не хотим, чтобы браузер заполнял форму. В листинге 12-5 показано, как это можно сделать, используя атрибут autocomplete
элемента form
.
Листинг 12-5: Отключение атрибутаautocomplete
элементаform
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<meta name="author" content="Adam Freeman" />
<meta name="description" content="A simple example" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
</head>
<body>
<form autocomplete="off" method="post" action="http://titan:8080/form">
<input name="fave" />
<input name="name" />
<button>Submit Vote</button>
</form>
</body>
</html>
Для атрибута autocomplete
есть два допустимых значения: on
и off
. Значение on
позволяет браузеру заполнять форму и является значением по умолчанию; то есть предполагается, что именно оно используется, если вы не применяете атрибут.
Вы можете конкретизировать задачу, применяя атрибут autocomplete
к отдельным элементам input
, как показано в листинге 12-6.
Листинг 12-6: Применение атрибутаautocomplete
к элементамinput
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<meta name="author" content="Adam Freeman" />
<meta name="description" content="A simple example" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
</head>
<body>
<form autocomplete="off" method="post" action="http://titan:8080/form">
<input autocomplete="on" name="fave" />
<input name="name" />
<button>Submit Vote</button>
</form>
</body>
</html>
Атрибут autocomplete
элемента form
устанавливает значение по умолчанию для элементов input
в форме. Но как показано в листинге, вы можете изменить эту политику для отдельных элементов. В этом примере атрибут элемента form
отключил автозаполнение, но тот же атрибут, примененный к первому элементу input
, включил его обратно, но только для этого элемента. Второй элемент input
, к которому не применяется атрибут autocomplete
, зависит от настроек формы.
Вообще autocomplete
стоит включать: пользователи привыкли к автоматическому заполнению формы и, как правило, сталкиваются с несколькими формами за время любой веб транзакции. Эта функция дает возможность соответствовать предпочтениям и привычкам пользователей. Я знаю по собственному опыту, что это довольно неприятно, когда я пытаюсь купить продукцию на сайтах, отключивших автозаполнение, особенно если оно отключено для такой базовой информации, как мое имя и адрес. Некоторые сайты отключают автозаполнение для данных кредитной карты, что имеет больше смысла, но даже в этом случае такой подход следует применять с осторожностью, и причины для отмены этой функции должны быть полностью продуманы.
Указание цели для ответа формы
По умолчанию браузер заменяет страницу, содержащую форму, ответом, который сервер возвращает после того, как форма была отправлена. Вы можете изменить это поведение при помощи атрибута target
элемента form
. Этот атрибут работает таким же образом, как и атрибут target
элемента a
, и вы можете выбрать нужное значение из тех, что показаны в таблице 12-6.
Таблица 12-6: Значения атрибутаtarget
элементаform
Атрибут | Описание |
_blank |
Открывает ответ сервера в новом окне (или вкладке) |
_parent |
Открывает ответ сервера в родительском фрейме |
_self |
Открывает ответ сервера в текущем окне (это поведение по умолчанию) |
_top |
Открывает ответ сервера на все окно |
<frame> |
Открывает ответ сервера в указанном фрейме |
Каждое из этих значений представляет браузерный контекст. Значения _blank
и _self
очевидны. Другие относятся к использованию фреймов, которые я объясню в главе 15. В листинге 12-7 показано, как атрибут target
применяется к элементу form
.
Листинг 12-7: Использование атрибута target
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<meta name="author" content="Adam Freeman" />
<meta name="description" content="A simple example" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
</head>
<body>
<form target="_blank" method="post" action="http://titan:8080/form">
<input autocomplete="on" name="fave" />
<input name="name" />
<button>Submit Vote</button>
</form>
</body>
</html>
В этом примере я указал цель _blank
, которая говорит браузеру отображать ответа сервера в новом окне или вкладке. На рисунке 12-3 вы можете увидеть результат этих изменений.
Рисунок 12-3: Отображение ответа сервера в новой вкладке
Установка имени формы
Атрибут name
позволяет задать для формы уникальный идентификатор, так что мы можем различать формы при работе с Document Object Model (DOM). Я представляю DOM в главе 25. Атрибут name
отличается от глобального атрибута id
, и в большинстве случаев HTML документы используют атрибут id
для CSS селекторов. В листинге 12-8 показан элемент form
, к которому были применены атрибуты name
и id
. Для простоты я использовал для обоих атрибутов одно и то же значение.
Листинг 12-8: Использование атрибутовname
иid
для элементаform
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<meta name="author" content="Adam Freeman" />
<meta name="description" content="A simple example" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
</head>
<body>
<form name="fruitvote" id="fruitvote"
method="post" action="http://titan:8080/form">
<input name="fave" />
<input name="name" />
<button>Submit Vote</button>
</form>
</body>
</html>
Значение атрибута name
не отправляется на сервер вместе с формой, поэтому этот атрибут имеет значение только в DOM, и он не так важен, как атрибут name элемента input
. Если элемент input
не имеет атрибута name
, то данные, введенные пользователем, не будут отправлены на сервер при отправке формы.