Диагностика проблемы повторной отправки формы
Проблема повторной отправки формы возникает, когда пользователь после успешной отправки формы обновляет страницу браузера (F5 или кнопка обновления). В результате форма повторно отправляется, что приводит к дублированию данных, например, повторным заказам или дублированию заявок.
Проверьте, действительно ли форма отправляется повторно при перезагрузке:
- Отправьте форму и дождитесь подтверждения отправки;
- Обновите страницу браузера;
- Проверьте, отправилось ли письмо повторно или появились дубликаты заявок в базе.
Если да — проблема подтверждена.
Почему происходит повторная отправка?
Контактная форма 7 по умолчанию использует метод POST, и браузер пытается повторить последний POST-запрос при обновлении страницы. Это стандартное поведение браузера, и его нужно корректно обработать.
Пошаговое решение: предотвращаем повторную отправку
1. Использование перенаправления после успешной отправки (Post/Redirect/Get)
Самый надежный способ — реализовать перенаправление на страницу благодарности после отправки формы. Это меняет метод с POST на GET, и обновление страницы уже не приведет к повторной отправке.
В Contact Form 7 это можно сделать с помощью JavaScript-хука wpcf7mailsent:
document.addEventListener('wpcf7mailsent', function(event) {
window.location.href = '/thank-you/';
}, false);Где /thank-you/ — адрес страницы с сообщением об успешной отправке.
2. Добавление скрытого поля с nonce для защиты
Для дополнительной защиты можно добавить nonce-токен в форму и проверять его на сервере, чтобы исключить повторную отправку с одного токена.
Пример создания nonce и добавления в форму через хук:
add_filter('wpcf7_form_elements', function($content) {
$nonce = wp_create_nonce('cf7_nonce');
$hidden_input = '<input type="hidden" name="cf7_nonce" value="' . esc_attr($nonce) . '" />';
return $content . $hidden_input;
});
add_action('wpcf7_before_send_mail', function($contact_form) {
$submission = WPCF7_Submission::get_instance();
if ($submission) {
$data = $submission->get_posted_data();
if (!isset($data['cf7_nonce']) || !wp_verify_nonce($data['cf7_nonce'], 'cf7_nonce')) {
// Останавливаем отправку
$contact_form->skip_mail = true;
}
}
});Это не отменит повторную отправку при обновлении страницы, но защитит от повторной обработки одинаковых данных.
3. Использование JavaScript для очистки формы и истории браузера
Можно очистить форму и заменить историю браузера с помощью history.replaceState, чтобы при обновлении не отправлять POST-запрос повторно:
document.addEventListener('wpcf7mailsent', function(event) {
event.target.reset();
if (window.history.replaceState) {
window.history.replaceState(null, null, window.location.href);
}
}, false);Этот способ подойдет, если не хотите создавать отдельную страницу благодарности.
Как проверить, что решение работает
- Отправьте форму;
- После успешной отправки выполните обновление страницы браузера;
- Проверьте, что письмо или данные не отправились повторно;
- При использовании перенаправления убедитесь, что адрес страницы изменился на страницу благодарности;
- В случае очистки формы после отправки убедитесь, что поля пусты, а повторная отправка не происходит.
Частые ошибки и их исправление
- Не работает JavaScript-перехват события — проверьте консоль браузера на ошибки, убедитесь, что скрипт подключен на странице и не конфликтует с другими скриптами.
- Перенаправление не происходит — убедитесь, что событие
wpcf7mailsentдействительно срабатывает, а URL указан корректно и ведет на существующую страницу. - Повторная отправка происходит несмотря на nonce — nonce защищает от CSRF, но не предотвращает повторную отправку при обновлении страницы, поэтому комбинируйте с перенаправлением или очисткой формы.
- Пользователь жалуется на потерю введенных данных — перенаправление сбрасывает форму, если хотите сохранить данные, используйте AJAX и локальное хранение (localStorage), но это усложняет реализацию.
Практические советы по безопасности и производительности
- Всегда применяйте nonce и валидируйте данные на сервере для защиты от CSRF и вредоносных запросов.
- Используйте перенаправление после отправки для улучшения UX и предотвращения повторной отправки.
- Минимизируйте подключение лишних скриптов, чтобы не создавать конфликтов с Contact Form 7.
- Для сайтов с высокой нагрузкой и большим количеством форм рассмотрите кеширование страниц с исключением страниц с формами или использование AJAX-отправки.
Таблица сравнения вариантов решения
| Метод | Плюсы | Минусы | Применение |
|---|---|---|---|
| Перенаправление (Post/Redirect/Get) | Надёжно предотвращает повторную отправку; Улучшает UX; | Требует отдельной страницы благодарности; | Рекомендуется для большинства случаев; |
| JavaScript очистка и replaceState | Не требует перенаправления; Быстрая реализация; | Не всегда предотвращает повторную отправку в 100%; Может сбросить данные; | Для простых форм без отдельной страницы; |
| Nonce и серверная проверка | Защищает от CSRF; Уменьшает риск повторной обработки; | Не предотвращает повторную отправку при обновлении браузера; | Обязателен для безопасности; |