Почему возникает повторная отправка формы при обновлении страницы?
В Contact Form 7, как и в большинстве форм на PHP, после успешной отправки пользователь остается на той же странице с формой. Если он обновит страницу браузера (F5 или Ctrl+R), браузер повторно отправит POST-запрос — то есть данные формы отправятся снова. Это может привести к дублированию заявок, повторным письмам и другим нежелательным эффектам.
Причина в стандартной работе HTTP-протокола и в том, что Contact Form 7 по умолчанию не реализует паттерн Post/Redirect/Get (PRG), который предотвращает повторную отправку при обновлении.
Как диагностировать проблему с повторной отправкой
- Отправьте форму и после успешного сообщения об отправке нажмите F5. Если форма отправится повторно — проблема налицо.
- Проверьте, сохраняется ли в адресной строке URL с параметрами, связанными с формой (обычно нет, но при нестандартных настройках может быть).
- Включите консоль браузера (F12) и наблюдайте за сетевыми запросами при обновлении страницы — если появляется POST-запрос, значит форма повторяется.
Пошаговое решение: реализация паттерна Post/Redirect/Get для Contact Form 7
Основная идея — после успешной отправки формы сделать редирект на ту же страницу с параметром, который сигнализирует об успешной отправке. Это переведет браузер в режим GET-запроса, и обновление страницы уже не будет повторно отправлять форму.
1. Добавляем редирект после успешной отправки формы
В functions.php вашей темы или в своем плагине добавьте следующий код, используя хук wpcf7_mail_sent:
add_action('wpcf7_mail_sent', 'cf7_redirect_after_submit');
function cf7_redirect_after_submit($contact_form) {
$submission = WPCF7_Submission::get_instance();
if ($submission) {
$url = $submission->get_meta('url'); // URL страницы с формой
// Добавляем параметр для уведомления об успехе
$redirect_url = add_query_arg('cf7submitted', '1', $url);
wp_redirect($redirect_url);
exit;
}
}
Этот код автоматически перенаправит пользователя на ту же страницу с параметром cf7submitted=1 после успешной отправки.
2. Показываем сообщение об успешной отправке по параметру URL
Чтобы пользователь видел подтверждение, можно в шаблоне страницы проверить параметр и вывести сообщение:
if (isset($_GET['cf7submitted']) && $_GET['cf7submitted'] === '1') {
echo '<div class="cf7-success-message">Спасибо! Ваша заявка отправлена.</div>';
}
3. Убираем стандартное сообщение Contact Form 7
Contact Form 7 по умолчанию показывает сообщение об успешной отправке. Чтобы не дублировать, можно отключить его через JavaScript или CSS, либо оставить и дополнить своим. Если хотите убрать, добавьте CSS:
.wpcf7-response-output { display: none !important; }
Проверка результата
- Отправьте форму с заполненными полями.
- Убедитесь, что после отправки происходит редирект и в адресной строке появляется
?cf7submitted=1. - Обновите страницу (F5) — повторной отправки формы не должно быть.
- Проверьте, что сообщение об успешной отправке видно.
Частые ошибки и как их исправить
- Редирект не срабатывает, форма не перенаправляется: Проверьте, что вызов
wp_redirectпроисходит до вывода любого контента. Если есть пробелы или echo до него — редирект не сработает. Поместите код в functions.php и убедитесь, что нет ошибок PHP. - Параметр
cf7submittedне добавляется к URL: Убедитесь, что$submission->get_meta('url')возвращает корректный URL страницы. Если форма выводится на нескольких страницах, убедитесь, что URL формируется правильно. - Сообщение об успешной отправке не отображается: Проверьте вывод проверки параметра GET и наличие HTML для сообщения. Также проверьте CSS, возможно сообщение скрыто стилями.
- Редирект вызывает бесконечный цикл: Убедитесь, что редирект происходит только при успешной отправке, а не при наличии параметра
cf7submittedв URL.
Практические советы по безопасности и производительности
- Всегда проверяйте и валидируйте данные формы с помощью стандартных возможностей Contact Form 7, чтобы избежать уязвимостей.
- Не используйте редиректы в хуках, если страница выводит контент с буферизацией, это может вызвать ошибки headers already sent.
- Для сложных форм с большим трафиком рассмотрите внедрение кеширования страниц с исключением страниц с формами.
- Используйте нативные методы Contact Form 7 для обработки, не меняйте глобальных переменных PHP.
Альтернативные варианты решения
| Метод | Плюсы | Минусы |
|---|---|---|
| Паттерн Post/Redirect/Get (редирект после отправки) | Простой, надежный, предотвращает повторную отправку | Требует доработки кода и обработки параметров в шаблоне |
| AJAX отправка формы | Отсутствует перезагрузка страницы, нет повторной отправки | Сложнее в реализации, требует JS, не для всех случаев подходит |
| Использование плагинов с защитой от дублирующих заявок | Простая установка, дополнительные функции | Может нагружать сайт, зависит от стороннего кода |
Итог
Для большинства случаев достаточно реализовать Post/Redirect/Get через хук wpcf7_mail_sent и редирект на страницу с параметром. Это решит проблему повторной отправки и улучшит UX без сложных доработок.