Кратко
Отправка формы: submit event → preventDefault() → собрать данные → fetch POST → обработать ответ. Два способа передачи данных: FormData (multipart/form-data) и JSON (application/json). FormData проще для начинающих. JSON — стандарт для API.
Подробно
Стандартная отправка формы (без JS): <form action="/api/users" method="POST">... При submit: браузер отправляет запрос и перезагружает страницу.
С JavaScript:
const form = document.querySelector('#myForm');
form.addEventListener('submit', async (e) => { e.preventDefault(); // отменяем перезагрузку
const formData = new FormData(form);
try { const response = await fetch('/api/users', { method: 'POST', body: formData // multipart/form-data автоматически });
if (!response.ok) throw new Error(HTTP ${response.status});
const result = await response.json(); console.log('Успех:', result); } catch (error) { console.log('Ошибка:', error.message); } });
JSON отправка:
form.addEventListener('submit', async (e) => { e.preventDefault();
const data = Object.fromEntries(new FormData(form));
const response = await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) });
if (!response.ok) throw new Error(HTTP ${response.status});
const result = await response.json();
});
FormData vs JSON:
- FormData: проще, автоматически форматирует, поддерживает файлы
- JSON: стандарт для API, нужен Content-Type, не поддерживает файлы
Состояние формы:
- loading: показать индикатор, заблокировать кнопку
- success: показать сообщение, очистить форму
- error: показать ошибку, не очищать форму
Ментальная модель
Отправка формы — как отправка заказа по почте. Вы заполняете форму (FormData), кладёте в конверт (request body), указываете адрес (URL), и отправляете (fetch). Почтальон (браузер) доставляет. Ответ приходит как уведомление о доставке (response).
Примеры
**Самый простой:**
<form id="form">
<input type="text" name="name">
<button type="submit">Отправить</button>
</form>
<script>
document.getElementById('form').addEventListener('submit', async (e) => {
e.preventDefault();
const data = new FormData(e.target);
console.log('Отправляем:', Object.fromEntries(data));
});
</script>Простейший перехват формы: preventDefault + FormData.
**Простой:**
const form = document.querySelector('#contactForm');
const status = document.querySelector('#status');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(form);
const data = Object.fromEntries(formData);
status.textContent = 'Отправка...';
try {
const response = await fetch('/api/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) throw new Error('Ошибка сервера');
status.textContent = 'Отправлено!';
form.reset(); // очищаем форму
} catch (error) {
status.textContent = `Ошибка: ${error.message}`;
}
});Полный цикл: отправка + индикатор + обработка ответа + очистка.
**Реальный пример:**
async function submitForm(form, options = {}) {
const {
url = form.action,
method = form.method || 'POST',
format = 'json'
} = options;
const submitBtn = form.querySelector('[type="submit"]');
submitBtn.disabled = true;
submitBtn.textContent = 'Отправка...';
try {
const formData = new FormData(form);
let body, headers = {};
if (format === 'json') {
body = JSON.stringify(Object.fromEntries(formData));
headers['Content-Type'] = 'application/json';
} else {
body = formData;
}
const response = await fetch(url, { method, headers, body });
if (!response.ok) {
const error = await response.text();
throw new Error(error || `HTTP ${response.status}`);
}
return await response.json();
} finally {
submitBtn.disabled = false;
submitBtn.textContent = 'Отправить';
}
}Универсальная функция отправки формы с поддержкой JSON и FormData.
Частые ошибки
**Неправильно:** Забывать preventDefault на submit
**Почему:** Без preventDefault форма отправится стандартно и страница перезагрузится.
**Правильно:** Всегда e.preventDefault() в начале submit handler.
**Неправильно:** Не блокировать кнопку во время отправки
**Почему:** Пользователь может нажать несколько раз → дублирующие запросы.
**Правильно:** submitBtn.disabled = true во время запроса, false в finally.
**Неправильно:** Не обрабатывать ошибки
**Почему:** Сетевые ошибки, ошибки сервера — обычные ситуации.
**Правильно:** Всегда try/catch + проверка response.ok.
Важно запомнить
- e.preventDefault() — отменяем стандартную отправку
- FormData — сбор данных формы
- JSON.stringify + Content-Type — для JSON API
- Блокируйте кнопку во время отправки
- Всегда обрабатывайте ошибки
Связь
Назад: Вы знаете формы (DA7) и fetch (JA7). Теперь вы объединяете их для реальной отправки форм.
Вперёд: Следующий урок (DA9) — события клавиатуры для навигации по формам и горячих клавиш.