Почему форма стирает всё, что я ввёл — 3 причины и как починить

Симптом знакомый до зубовного скрежета. Человек заполняет форму, жмёт «Отправить», страница моргает — и наверху висит «Проверьте правильность полей». А поля пустые. Все. Включая те, где всё было верно.
Дальше происходит понятное: половина людей уходит. Они не чинят твою опечатку в валидации — они закрывают вкладку.
Хорошая новость: причин у этого всего три, и все три видно за пару минут.
Причина 1: сервер отдал форму заново, но пустую
Самая частая. Форма отправляется обычным способом, сервер проверяет данные, находит ошибку и... рендерит ту же страницу с нуля. Шаблон-то один — тот же, что показывался в первый раз. А в первый раз поля были пустыми.
Как проверить. Открой панель разработчика, вкладку «Сеть», отправь форму с ошибкой. Если там появился запрос POST, который вернул целую HTML-страницу, — это твой случай. Посмотри в ответе на свои поля: увидишь value="" там, где человек только что печатал.
Как починить. Отдавать форму заполненной — тем, что прислал человек:
<input name="email" value="{{ email }}" />
Для <select> возвращай selected, для чекбоксов — checked. Дизайн-система GOV.UK описывает это как обязательную часть обработки ошибок: показать страницу снова, с полями в том виде, как их заполнил человек. По их формулировке, сохранённые данные позволяют увидеть, что пошло не так, поправить прошлый ответ и не вводить всё заново.
Одна оговорка: поле пароля обычно не возвращают — и это нормально, люди к этому привыкли.
Причина 2: форма перерисовалась на клиенте
Если сетевого запроса вообще нет, а поля всё равно опустели — форму перерисовал твой же JavaScript.
Типичная механика во фреймворках вроде React: при ошибке меняется состояние, и форма показывается уже в другой ветке рендера — или у неё меняется key. Для фреймворка это другая форма, а не та же самая. Старые поля уничтожаются вместе с содержимым.
Как проверить. Поставь console.log в начало компонента формы. Если после нажатия «Отправить» лог печатается, а введённого текста в полях нет — компонент пересоздался.
Как починить. Значения полей должны жить выше того места, которое перерисовывается: в состоянии родителя или в одном объекте формы. Тогда любая перерисовка возвращает поля заполненными. И не прячь форму целиком, чтобы показать ошибку, — рисуй ошибку рядом с ней.
Причина 3: «Назад» не восстановил страницу
Отдельный сценарий: человек ушёл на следующий экран, нажал «Назад» — и вернулся к пустой форме.
Обычно браузер восстанавливает предыдущую страницу целиком из памяти (эта штука называется bfcache) вместе с введёнными значениями. Но страницу могут в этот кэш не положить.
Как проверить. Повесь обработчик и посмотри, что происходит при возврате:
window.addEventListener("pageshow", (event) => {
console.log("восстановлено из bfcache:", event.persisted);
});
false при нажатии «Назад» означает, что страница грузилась заново — значит, в кэш её не пустили.
Как починить. Две самые частые причины:
- Обработчик
unload. Руководство web.dev формулирует без полутонов: не используй событиеunload, никогда. Chrome и Firefox на десктопе делают страницу с таким обработчиком непригодной для bfcache. Замена —pagehide, оно срабатывает во всех тех же случаях. - Заголовок
Cache-Control: no-storeна самой странице. Исторически браузеры не кладут такие страницы в bfcache. На страницах за логином он часто стоит «на всякий случай» — проверь, правда ли он нужен именно здесь.
Что сделать один раз, чтобы больше не терять
Сохраняй черновик по мере ввода — это страхует сразу от всех трёх причин, включая случайно закрытую вкладку:
form.addEventListener("input", () => {
const data = Object.fromEntries(new FormData(form));
localStorage.setItem("draft", JSON.stringify(data));
});
При загрузке страницы подставь сохранённое обратно, а после успешной отправки — удали ключ, чтобы черновик не всплыл в следующий раз.
И проверь заодно текст самой ошибки: «Проверьте правильность полей» не говорит человеку ничего. Нужно, какое поле и что с ним не так. Если форма длинная, это ещё и повод разбить её на шаги — терять один экран из четырёх куда менее обидно.
Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.
Почему поля пустеют только иногда?
Скорее всего, у тебя причина 3: она проявляется только при возврате «Назад» и по-разному ведёт себя в разных браузерах. Причины 1 и 2 воспроизводятся всегда — если ошибка каждый раз стирает форму, ищи там.
Можно починить это, не трогая сервер?
Если форма отправляется обычным POST с перезагрузкой — нет, значения возвращает сервер. Но черновик в localStorage работает всегда и не требует ничего, кроме нескольких строк на клиенте. Это хорошая временная заплатка, пока чинишь причину.





