Формы и валидация в JavaScript: обработка ввода
Содержание
О проверке кода. Примеры не запускались в браузере — в отличие от материалов по Node.js с фактическим выводом. Говорим прямо, а не ставим бейдж «проверено».
Формы — главный способ получить данные от пользователя. Их обработка в JavaScript строится вокруг события submit и проверки ввода. Разберём полный цикл: перехват, чтение, валидацию, отправку.
Перехват отправки
const form = document.querySelector('#signup');
form.addEventListener('submit', (event) => {
event.preventDefault(); // отменяем перезагрузку страницы
// теперь обрабатываем данные сами
});
Слушают событие submit на самой форме и вызывают preventDefault. По умолчанию отправка формы перезагружает страницу — в приложении на JavaScript это не нужно, данные шлют через fetch. Обработчик вешают именно на submit формы, а не на click кнопки: submit срабатывает и при нажатии Enter в поле.
Чтение значений полей
form.addEventListener('submit', (event) => {
event.preventDefault();
// FormData собирает все поля по атрибуту name
const data = Object.fromEntries(new FormData(form));
// { email: 'a@b.ru', password: '123', name: 'Аня' }
console.log(data.email);
});
FormData собирает все поля формы по атрибуту name, а Object.fromEntries превращает их в обычный объект — удобно отправлять как JSON. Для одного поля можно и напрямую: form.elements.email.value или через querySelector. FormData также умеет файлы и сразу подходит для отправки multipart/form-data.
Встроенная валидация HTML5
Многое браузер проверяет сам, без JavaScript:
<input type="email" required> <!-- обязательное, формат email -->
<input type="text" minlength="3" maxlength="20">
<input type="number" min="18" max="100">
<input type="text" pattern="[A-Za-z]+"> <!-- по регулярке -->
// прочитать результат встроенной проверки
if (!input.checkValidity()) {
console.log(input.validationMessage); // готовый текст ошибки от браузера
}
input.validity.valueMissing; // true, если required пустое
input.validity.typeMismatch; // true, если формат не тот
Атрибуты required, type="email", min, pattern — это встроенная валидация, которую браузер выполняет сам. JavaScript читает её результат через checkValidity() и input.validity, не проверяя базовые правила вручную. Это экономит код: не надо писать регулярку для email, если хватает type="email".
Своя валидация
Когда встроенных правил мало (совпадение паролей, проверка на сервере), пишут свою:
function validate(data) {
const errors = {};
if (!data.email.includes('@')) {
errors.email = 'Некорректный email';
}
if (data.password.length < 8) {
errors.password = 'Минимум 8 символов';
}
if (data.password !== data.passwordConfirm) {
errors.passwordConfirm = 'Пароли не совпадают';
}
return errors; // { } если всё ок
}
Своя проверка возвращает объект ошибок по полям. Функция чистая — принимает данные, возвращает ошибки, ничего не трогает в DOM. Это упрощает тестирование и повторное использование.
Показ ошибок
form.addEventListener('submit', (event) => {
event.preventDefault();
const data = Object.fromEntries(new FormData(form));
const errors = validate(data);
// очистить прошлые ошибки
form.querySelectorAll('.error').forEach(el => el.textContent = '');
if (Object.keys(errors).length > 0) {
// показать ошибки рядом с полями
for (const [field, message] of Object.entries(errors)) {
const errorEl = form.querySelector(`[data-error="${field}"]`);
if (errorEl) errorEl.textContent = message;
}
return; // не отправляем
}
submitForm(data); // всё валидно — отправляем
});
Ошибки показывают рядом с полями: находят элемент для сообщения и пишут текст через textContent (не innerHTML — это пользовательский контекст). Перед показом чистят прошлые ошибки. Object.entries перебирает пары «поле — сообщение».
Отправка данных
async function submitForm(data) {
try {
const response = await fetch('/api/signup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
if (!response.ok) throw new Error(`Ошибка ${response.status}`);
form.reset(); // очистить форму
showSuccess('Готово!');
} catch (error) {
showError('Не удалось отправить. Попробуйте позже.');
}
}
Валидные данные уходят POST-запросом с JSON, ошибки ловятся try/catch. После успеха — form.reset() очищает поля.
Главное правило безопасности
Клиентская — для удобства
Быстрая обратная связь
- Мгновенная подсказка без запроса
- Улучшает UX
- Экономит запросы к серверу
- НО легко обходится
Серверная — для безопасности
Единственная надёжная
- Клиентский код можно отключить
- Запрос можно подделать напрямую
- Сервер проверяет ВСЕГДА
- Никогда не доверяй данным клиента
Клиентская валидация не заменяет серверную. Она нужна для удобства — мгновенная подсказка без обращения к серверу. Но её легко обойти: отключить JavaScript или отправить запрос напрямую. Поэтому сервер проверяет данные всегда, независимо от клиента. Правило простое: клиент — для UX, сервер — для безопасности, доверять данным клиента нельзя.
Смежные темы: события DOM — submit и preventDefault; fetch — отправка данных; методы Object — FormData в объект; валидация в Express — серверная сторона. Полный список — в уроках JavaScript.