Скрытое поле в контактной форме — honeypot
запись от - 1 апреля 2024Honeypot — очень простой и довольно эффективный способ уменьшить количество спама в формах Contact Form 7 без лишних неудобств для пользователей.
Идея в том что в форму помещается скрытое поле, которое заполнять не надо. Тупые (простые) боты заполняют все подряд — соответственно если поле заполнено, форму не отправляем, содержимое считаем спамом.
Скачать можно здесь — https://github.com/vvhromov/cf7honeypot
Так выглядит форма в панели редактирования Contact Form 7
<div class="simple-form">
<label> Просто текстовое поле
[text simple-text] </label>
[honeypot extra]
[submit "Отправить"]
</div>
А так выглядит эта форма на странице — проще некуда, текстовое поле и кнопка «Отправить»
Но если посмотреть форму Инспектором (DevTools) можно увидеть что есть еще одно скрытое поле.
Делается это так
function cf7_honeypot_form_tag_handler( $tag ) {
return '<input type="text" name="'.esc_attr( $tag->name ).'" value="" style="display:none!important" autocomplete="off" tabindex="-1" />';
}
// Добавляется тег [honeypot {name-tag}] в CF7
// function cf7_honeypot_form_tag_handler определяет как honeypot будет выводится на веб странице
add_action(
'wpcf7_init',
function () {
wpcf7_add_form_tag( 'honeypot', 'cf7_honeypot_form_tag_handler', [ 'name-attr' => true ] );
}
);
Шоткод [honeypot extra] добавил в форму поле типа text с именем extra. Подробней можно почитать здесь — https://contactform7.com/2015/01/10/adding-a-custom-form-tag/
Теперь при получении формы остается проверить что это поле не заполнено, тогда считаем что форма заполнена человеком. Человек просто не увидит это поле. Если поле заполнено, считаем что заполнял робот и отправляем информацию в спам.
А проверяем так
// Custom validation - https://contactform7.com/2015/03/28/custom-validation/
function cf7_validate_honeypot( $result, $tag ) {
$name = $tag->name;
$value = isset( $_POST[$name] ) ? trim( $_POST[$name] ) : '';
if ( $value !== '' ) {
$result->invalidate( $tag, "Ошибка: форма заполнена неправильно." );
}
return $result;
}
add_filter( 'wpcf7_validate_honeypot', 'cf7_validate_honeypot', 10, 2 );
При отладке всей этой радости возникают вопросы.
Как отменить отправку формы на почту во время экспериментов — можно так
И еще вопрос. Как заполнить то самое скрытое поле и автоматически отправить форму, чтобы проверить что все работает корректно.
Вот такая кнопка и JS скрипт решают проблему
window.addEventListener( 'load', function() {
// console.log('All assets are loaded');
//
// stupid bot
//
// в редакторе страницы WP к кнопке на вкладке "Дополнительно"
// надо добавить класс button-fill
const button_fill = document.querySelector('.button-fill');
button_fill.onclick = function() {
// при нажатии на кнопку заполняются поля формы
// 'extra' - скрытое поле honeypot
// форма отправляется на сервер
// если форма единственная на странице, к ней можно обратится const form = document.forms[0];
// const form = document.forms[0];
// Чтобы обратиться к форме по id в шоткоде нужно добавить html_id
// [contact-form-7 id="0729efd" title="Test form with one field" html_id="form-with-honeypot"]
const form = document.forms['form-with-honeypot'];
form.elements['simple-text'].value = new Date();;
form.elements['extra'].value = "some text";
form.submit();
alert('Форма отправлена на сервер - все поля заполнены');
};
} );
Скачать можно здесь — https://github.com/vvhromov/cf7honeypot
Если нет времени или желания разбираться самостоятельно – обращайтесь