Проверка ограничений
Создание веб-форм всегда было сложной задачей. Хотя маркировка самой формы проста, проверка того, имеет ли каждое поле допустимое и согласованное значение, сложнее, а информирование пользователя о проблеме может стать головной болью. HTML5 ввёл новые механизмы для форм: он добавил новые семантические типы для элемента <input> и проверку ограничений, чтобы облегчить работу по проверке содержимого формы на стороне клиента. Базовые, обычные ограничения можно проверять, не прибегая к JavaScript, задавая новые атрибуты; более сложные ограничения можно проверять с помощью API проверки ограничений.
Для базового введения в эти концепции с примерами см. учебник по проверке форм.
Примечание: Проверка ограничений HTML не исключает необходимости проверки на серверной стороне. Несмотря на то, что ожидается значительно меньше некорректных запросов формы, некорректные запросы всё ещё могут быть отправлены множеством способов:
- Путем изменения HTML через инструменты разработчика браузера.
- Путем ручного создания запроса HTTP без использования формы.
- Путем программной записи содержимого в форму (некоторые проверки ограничений выполняются только для ввода пользователем, а не если вы задаёте значение поля формы с помощью JavaScript).
Поэтому всегда следует проверять данные формы на серверной стороне, в соответствии с тем, что выполняется на стороне клиента.
Встроенные и базовые ограничения
В HTML базовые ограничения объявляются двумя способами:
- Выбирая наиболее семантически подходящее значение для атрибута
typeэлемента<input>, например, выбор типаemailавтоматически создаёт ограничение, проверяющее, является ли значение допустимым адресом электронной почты. - Устанавливая значения связанных с проверкой атрибутов, позволяя описывать базовые ограничения простым способом, без необходимости использования JavaScript.
Семантические типы ввода
Встроенные ограничения для атрибута type следующие:
| Тип ввода | Описание ограничения | Связанное нарушение |
|---|---|---|
<input type="URL"> | Значение должно быть абсолютным URL, как определено в URL Living Standard. | Ошибка типа нарушение ограничения |
<input type="email"> | Значение должно быть синтаксически корректным адресом электронной почты, который обычно имеет формат username@hostname.tld, но также может быть локальным, например username@hostname. | Ошибка типа нарушение ограничения |
Для обоих этих типов ввода, если атрибут multiple установлен, можно задать несколько значений в виде списка, разделённого запятыми. Если хотя бы одно из этих значений не соответствует описанным здесь условиям, возникает нарушение ограничения Ошибка типа.
Обратите внимание, что у большинства типов ввода нет встроенных ограничений, так как некоторые из них запрещены для проверки ограничений или имеют алгоритм очистки, преобразующий некорректные значения в корректное значение по умолчанию.
Атрибуты, связанные с проверкой
В дополнение к атрибуту type, описанному выше, для описания базовых ограничений используются следующие атрибуты:
| Атрибут | Поддерживаемые типы ввода | Возможные значения | Описание ограничения | Связанное нарушение |
|---|---|---|---|---|
pattern | text, search, url, tel, email, password | Регулярное выражение JavaScript (скомпилированное с флагами global, ignoreCase и multiline выключенными) | Значение должно соответствовать шаблону. | patternMismatch нарушение ограничения |
min |
range, number
| Допустимое число | Значение должно быть больше или равно указанному значению. | rangeUnderflow нарушение ограничения |
date, month, week
| Допустимая дата | |||
datetime-local, time
| Допустимая дата и время | |||
max |
range, number
| Допустимое число | Значение должно быть меньше или равно указанному значению. | rangeOverflow нарушение ограничения |
date, month, week
| Допустимая дата | |||
datetime-local, time
| Допустимая дата и время | |||
required | text, search, url, tel, email, password, date, datetime-local, month, week, time, number, checkbox, radio, file; также на элементах <select> и <textarea> | нет, так как это атрибут булевого типа: его наличие означает истина, его отсутствие означает ложь | Должно быть значение (если задано). | valueMissing нарушение ограничения |
step | date | Целое число дней | Если шаг не установлен в значение any, значение должно быть min + целое кратное шагу. | stepMismatch нарушение ограничения |
month | Целое число месяцев | |||
week | Целое число недель | |||
datetime-local, time
| Целое число секунд | |||
range, number
| Целое число | |||
minlength | text, search, url, tel, email, password; также на элементе <textarea> | Длина целого числа | Количество символов (кодовых точек) не должно быть меньше значения атрибута, если он не пуст. Все новые строки нормализуются в один символ (в отличие от пар CRLF) для <textarea>. | tooShort нарушение ограничения |
maxlength | text, search, url, tel, email, password; также на элементе <textarea> | Длина целого числа | Количество символов (кодовых точек) не должно превышать значения атрибута. | tooLong нарушение ограничения |
Процесс проверки ограничений
Проверка ограничений выполняется с помощью API проверки ограничений либо для отдельного элемента формы, либо на уровне всей формы, на элементе <form> самом по себе. Проверка ограничений выполняется следующим образом:
- Вызовом метода
checkValidity()илиreportValidity()интерфейса DOM, связанного с формой, (HTMLInputElement,HTMLSelectElement,HTMLButtonElement,HTMLOutputElementилиHTMLTextAreaElement), который оценивает ограничения только для этого элемента, позволяя скрипту получить эту информацию. МетодcheckValidity()возвращает значение Boolean, указывающее, соответствует ли значение элемента его ограничениям. (Это обычно выполняется пользовательским агентом при определении, какие из псевдоклассов CSS,:validили:invalid, применяются.) В отличие от этого, методreportValidity()сообщает пользователю о любых нарушениях ограничений. - Вызовом метода
checkValidity()илиreportValidity()интерфейсаHTMLFormElement. - Путем отправки самой формы.
Вызов checkValidity() называется статической проверкой ограничений, в то время как вызов reportValidity() или отправка формы называется взаимодействующей проверкой ограничений.
Примечание:
- Если атрибут
novalidateустановлен для элемента<form>, взаимодействующая проверка ограничений не происходит. - Вызов метода
submit()интерфейсаHTMLFormElementне вызывает проверку ограничений. Другими словами, этот метод отправляет данные формы на сервер, даже если они не удовлетворяют ограничениям. Вместо этого вызовите методclick()на кнопке отправки. - Ограничения
minlengthиmaxlengthпроверяются только на пользовательском вводе. Они не проверяются, если значение установлено программно, даже при явном вызовеcheckValidity()илиreportValidity().
Сложные ограничения с помощью API проверки ограничений
Используя JavaScript и API ограничений, можно реализовать более сложные ограничения, например, ограничения, объединяющие несколько полей, или ограничения, включающие сложные вычисления.
В основном, идея заключается в том, чтобы вызвать JavaScript при возникновении события в поле формы (например, onchange), чтобы вычислить, нарушено ли ограничение, а затем использовать метод field.setCustomValidity() для установки результата проверки: пустая строка означает, что ограничение выполняется, а любая другая строка означает ошибку, и эта строка — сообщение об ошибке, которое нужно отобразить пользователю.
Объединение ограничений нескольких полей: проверка почтового индекса
Формат почтового индекса отличается от страны к стране. Большинство стран допускают необязательный префикс с кодом страны (например, D- в Германии, F- во Франции или Швейцарии), но в некоторых странах почтовые индексы содержат только фиксированное количество цифр; другие, как, например, Великобритания, имеют более сложную структуру, допускающую буквы в определенных позициях.
Примечание: Это не полная библиотека проверки почтовых индексов, а скорее демонстрация основных концепций.
В качестве примера добавим скрипт, проверяющий проверку ограничений для этой простой формы:
<form> <label for="ZIP">ZIP : </label> <input type="text" id="ZIP" /> <label for="Country">Country : </label> <select id="Country"> <option value="ch">Switzerland</option> <option value="fr">France</option> <option value="de">Germany</option> <option value="nl">The Netherlands</option> </select> <input type="submit" value="Validate" /> </form>
Это отображает следующую форму:
Сначала напишем функцию, проверяющую само ограничение:
function checkZIP() { // For each country, defines the pattern that the ZIP has to follow const constraints = { ch: [ "^(CH-)?\\d{4}$", "Switzerland ZIPs must have exactly 4 digits: e.g. CH-1950 or 1950", ], fr: [ "^(F-)?\\d{5}$", "France ZIPs must have exactly 5 digits: e.g. F-75012 or 75012", ], de: [ "^(D-)?\\d{5}$", "Germany ZIPs must have exactly 5 digits: e.g. D-12345 or 12345", ], nl: [ "^(NL-)?\\d{4}\\s*([A-RT-Z][A-Z]|S[BCE-RT-Z])$", "Netherland ZIPs must have exactly 4 digits, followed by 2 letters except SA, SD and SS", ], }; // Read the country id const country = document.getElementById("Country").value; // Get the NPA field const ZIPField = document.getElementById("ZIP"); // Build the constraint checker const constraint = new RegExp(constraints[country][0], ""); console.log(constraint); // Check it! if (constraint.test(ZIPField.value)) { // The ZIP follows the constraint, we use the ConstraintAPI to tell it ZIPField.setCustomValidity(""); } else { // The ZIP doesn't follow the constraint, we use the ConstraintAPI to // give a message about the format required for this country ZIPField.setCustomValidity(constraints[country][1]); } }
Затем свяжем ее с событием onchange для <select> и событием oninput для <input>:
window.onload = () => { document.getElementById("Country").onchange = checkZIP; document.getElementById("ZIP").oninput = checkZIP; };
Ограничение размера файла перед его загрузкой
Еще одно распространенное ограничение — ограничение размера загружаемого файла. Проверка этого на стороне клиента перед передачей файла на сервер требует объединения API проверки ограничений, а именно метода field.setCustomValidity() , с другим API JavaScript, в данном случае с API файлов.
Вот часть HTML:
<label for="FS">Select a file smaller than 75 kB : </label> <input type="file" id="FS" />
Это отображает:
JavaScript считывает выбранный файл, использует метод File.size() для получения его размера, сравнивает его с (заданным жестко) лимитом и вызывает API ограничений, чтобы сообщить браузеру о нарушении:
function checkFileSize() { const FS = document.getElementById("FS"); const files = FS.files; // If there is (at least) one file selected if (files.length > 0) { if (files[0].size > 75 * 1024) { // Check the constraint FS.setCustomValidity("The selected file must not be larger than 75 kB"); FS.reportValidity(); return; } } // No custom constraint violation FS.setCustomValidity(""); }
Наконец, мы подключаем метод к нужному событию:
window.onload = () => { document.getElementById("FS").onchange = checkFileSize; };
Визуальное форматирование проверки ограничений
Помимо установки ограничений, веб-разработчики хотят управлять отображаемыми сообщениями для пользователей и их стилями.
Управление внешним видом элементов
Внешний вид элементов можно контролировать с помощью псевдоклассов CSS.
:required и :optional псевдоклассы CSS
Псевдоклассы :required и :optional псевдоклассы позволяют создавать селекторы, которые соответствуют элементам формы, имеющим атрибут required, или не имеющим его.
:placeholder-shown псевдокласс CSS
См. :placeholder-shown.
:valid :invalid псевдоклассы CSS
Псевдоклассы :valid и :invalid псевдоклассы используются для представления элементов <input>, чье содержимое проходит проверку и не проходит проверку, соответственно, в соответствии с настройками типа ввода. Эти классы позволяют пользователю стилизовать элементы формы, соответствующие или не соответствующие требованиям, чтобы упростить идентификацию элементов, отформатированных правильно или неправильно.
Управление текстом нарушения ограничения
Следующие пункты могут помочь управлять текстом нарушения ограничения:
- Метод
setCustomValidity(message)для следующих элементов:-
<fieldset>. Примечание: Установка пользовательского сообщения об отсутствии валидности для элементов fieldset не предотвратит отправку формы в большинстве браузеров. <input><output><select>- Кнопки отправки (созданные с помощью элемента
<button>с типомsubmitили элементаinputс типом submit. Другие типы кнопок не участвуют в проверке ограничений). <textarea>
-
- Интерфейс
ValidityStateописывает объект, возвращаемый свойствомvalidityтипов элементов, перечисленных выше. Он представляет различные способы, которыми введенное значение может быть невалидным. Вместе они помогают объяснить, почему значение элемента не проходит проверку, если оно не валидно.
© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation