Блог
AJAX-отправка формы: отправить форму без перезагрузки страницы
· 4 мин чтения
Отправьте HTML-форму обычным способом - и браузер сделает то, что делал всегда: перейдёт на новую страницу или перезагрузит текущую, отбросив всё, что было на экране мгновение назад. Для формы, живущей на собственной странице, это безобидно. Но для формы внутри модального окна, чат-виджета, процесса оформления заказа или любого одностраничного приложения полная навигация - это резкий сброс: модальное окно закрывается, приложение монтируется заново, позиция прокрутки теряется. AJAX-отправка - отправка данных формы через JavaScript-функцию fetch() вместо того, чтобы позволить браузеру перейти на другую страницу - решает эту проблему, и для неё нужно всего несколько строк кода.
Зачем избегать перезагрузки страницы
Полная перезагрузка страницы отбрасывает всё, что JavaScript держал в памяти: открытое модальное окно, текущий шаг мастера, несохранённое состояние в другом месте страницы. Если форма живёт внутри дерева компонентов React, Vue или Svelte, переход браузера на другую страницу также разрушает всё клиентское приложение, которое затем приходится загружать заново с нуля.
Отправка через fetch() сохраняет страницу - и приложение, работающее на ней, - нетронутыми. Вы сами решаете, что произойдёт дальше: показать сообщение об успехе прямо на странице, закрыть модальное окно, сбросить поля, при необходимости перенаправить программно. В этом разница между «браузер решает» и «решаете вы».
Это улучшение, а не требование
Вам не нужно выбирать один из двух подходов. Оставьте атрибуты action и method у тега <form> точно такими же, как для обычного POST-запроса, и перехватывайте событие отправки через JavaScript только когда он доступен. Если скрипт не загрузился, расширение браузера вмешалось, или у посетителя вовсе отключён JavaScript, форма всё равно работает - она просто откатывается к обычной навигации по странице вместо встроенного сообщения о статусе. В этом вся суть прогрессивного улучшения: базовый случай - HTML-форма, отправляющая данные напрямую на https://formhook.app/f/{apiKey}, - всегда работает сама по себе. JavaScript лишь делает это приятнее, когда он есть.
Минимальный пример
Никакого фреймворка не требуется - вот весь паттерн на чистом JavaScript. Он предотвращает переход по умолчанию, отправляет данные формы как FormData и подставляет сообщение о статусе в зависимости от результата:
const form = document.querySelector("#contact-form");
form.addEventListener("submit", async (e) => {
e.preventDefault();
const res = await fetch(form.action, {
method: "POST",
body: new FormData(form),
headers: { Accept: "application/json" },
});
if (res.ok) {
form.reset();
document.querySelector("#form-status").textContent = "Thanks - we got it.";
} else {
document.querySelector("#form-status").textContent = "Something went wrong. Please try again.";
}
});Запрашивайте JSON, а не редирект
Обратите внимание на заголовок Accept: application/json в примере выше. Без него бэкенд форм, рассчитанный ещё и на обычные HTML-отправки, может попытаться перенаправить браузер на страницу «спасибо» - правильное поведение для обычного POST-запроса, но бесполезное, когда вы вызываете его из fetch(). Отправка Accept: application/json сообщает эндпоинту Formhook, что запрос пришёл из JavaScript, поэтому он возвращает JSON-ответ об успехе или ошибке вместо редиректа, и ваш код может ветвиться по res.ok, как в примере. Точный формат запроса смотрите в документации.
Не забудьте про доступность
Подстановка сообщения о статусе через textContent невидима для программ чтения с экрана, если только вы не попросите браузер объявить её вслух. Добавьте элементу статуса (тому самому, на который указывает document.querySelector("#form-status") в примере) атрибут aria-live="polite", и вспомогательные технологии озвучат обновление в момент его изменения - успех это или ошибка, - без того, чтобы посетителю пришлось самому находить элемент и переводить на него фокус. Это всего один атрибут, и именно он определяет разницу между формой, которая работает для всех, и формой, которая незаметно исключает пользователей экранных дикторов в тот момент, когда управление берёт на себя JavaScript.
Ничего из этого не требует библиотеки или SDK - эндпоинт Formhook принимает обычный POST-запрос формы с любого сайта, а версия с fetch() выше - лишь необязательное прогрессивное улучшение поверх этого, а не обязательное условие. Полный справочник по запросам и ответам смотрите в документации, а лимиты бесплатного тарифа - на странице цен.
Рабочая форма в одну строку
Размещение в ЕС, отправки хранятся вечно, push-уведомления на любом тарифе.
Начать бесплатноБез банковской карты · читайте документацию
Читать дальше
- Отправка данных формы в Slack (без кода)Email-оповещения теряются во входящих. Вот как отправлять данные форм с сайта прямо в канал Slack - самостоятельный способ и способ без единой строчки кода.
- Лучшие практики для контактной формы, которая действительно конвертируетКаждое лишнее поле - это шанс потерять посетителя. Практические советы: поля, подписи, мобильные устройства, honeypot и подтверждение отправки.
- Что такое бэкенд форм? (И когда он вам нужен)Бэкенд форм принимает, хранит и пересылает отправки форм вашего сайта, чтобы вам не пришлось запускать сервер. Вот как это работает и когда он вам нужен.