DOM Advanced

Отправка форм

Научиться отправлять формы через fetch: перехватить submit, собрать данные (FormData или JSON), отправить запрос и обработать ответ.

Продвинутый (Advanced)

Кратко

Отправка формы: 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).


Примеры

**Самый простой:**

html
<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.

**Простой:**

javascript
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}`;
  }
});

Полный цикл: отправка + индикатор + обработка ответа + очистка.

**Реальный пример:**

javascript
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) — события клавиатуры для навигации по формам и горячих клавиш.

Материалы курса DOM Advanced — PROlab Academy.