Наверх

Защита от спама формы на AjaxForm

У FormIt есть стандартный функционал защиты от спама — проверка любого поля на пустоту. Если робот-спамер заполнит такое поле, то письмо не будет отправлено.

Единственный минус этого способа в том, что ответ от сервера приходит с ошибкой валидации — по ответу сразу видно, что письмо не отправлено и нужно робота перенастроить.

В итоге такой способ задерживает меньше спама, чем мог бы.

Обычно на сайтах я использую связку FormIt + AjaxForm. Вот небольшое решение для фильтрации спама на этой связке. Оно похоже на стандартную валидацию с одним лишь условием — если поле заполнено и письмо решено не отправлять, спамеру сервер ответит сообщением с успехом отправки. В итоге спам-робот и его хозяин будут считать, что отправка работает, а у клиента на почте спама не будет.

Добавляем в форму поле, по которому будем фильтровать
<input type="text" name="surname" class="form-input" placeholder="Фамилия">

Прячем её стилями
input[name="surname"] {
    display: block;
    width: 2px;
    height: 3px;
    margin-bottom: -3px;
    opacity: 0.01;
}

Создаём сниппет checkSpam
<?php
if ($_POST['surname']) { // проверяем наше поле на пустоту
    echo $AjaxForm->success('Ваше сообщение отправлено');
    die();
} else {
    return true;
}

Добавляем наш сниппет в качестве хука перед email
'hooks' => 'checkSpam,email',

Теперь если письмо не отправлено, спамеру всё равно будет показано сообщение об успехе.


5 комментариев

  1. Denis Efremov 08 августа 2017, 13:00 # 0
    А я сначала на клиенте чекаю
    import extend from 'extend'
    
    /**
     * Class Validator.
     *
     * @class      Validator
     */
    export default class Validator {
    
        /**
         * Constructs the object.
         *
         * @param      {Object}  config  The configuration
         */
        constructor (config) {
            if (config === undefined) {
                config = this.defaults
            }
    
            this.config = extend(this.defaults, config)
        }
    
        /**
         * Get the default config
         *
         * @return     {Object}
         */
        get defaults () {
            return {
                styles: {
                    success: {
                        borderColor: '#4CAF50',
                        boxShadow: 'inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(76, 175, 80, 0.6)',
                    },
                    error: {
                        borderColor: '#E91E63',
                        boxShadow: 'inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(233, 30, 99, 0.6)',
                    },
                },
                rules: {
                    name (value) {
                        return value.length > 1
                    },
                    phone (value) {
                        return value.match(/\+7 \(\d\d\d\) \d\d\d-\d\d-\d\d/)
                    }
                }
            }
        }
    
        /**
         * Pass the validation
         *
         * @param      {HTMLElement}  el
         */
        pass (el) {
            this.setStyle(el, this.config.styles.success)
        }
    
        /**
         * Fail the validation
         *
         * @param      {HTMLElement}  el
         */
        fail (el) {
            this.setStyle(el, this.config.styles.error)
        }
    
        /**
         * Check the value
         *
         * @param      {Event}  e
         */
        check (e) {
            return this.config.rules[e.target.name](e.target.value)
                ? this.pass(e.target)
                : this.fail(e.target)
        }
    
        /**
         * Sets the style.
         *
         * @param      {HTMLElement}  el
         * @param      {Object}       styles  The styles
         */
        setStyle (el, styles) {
            Object.keys(styles).forEach(prop => {
                el.style[prop] = styles[prop]
            })
        }
    }
    
    И юзаю
            const vally = new Validator(),
    
            validate = (e) => {
                vally.check(e)
            },
    
            initForm = () => {
                textMask({
                    inputElement: phoneInput,
                    mask: ['+', '7', ' ', '(', /[1-9]/, /\d/, /\d/, ')',
                        ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, '-', /\d/, /\d/],
                })
    
                phoneInput.removeEventListener('keyup', validate)
                phoneInput.addEventListener('keyup', validate)
    
                nameInput.removeEventListener('keyup', validate)
                nameInput.addEventListener('keyup', validate)
            }
    
    1. Илья Уткин 08 августа 2017, 13:16 # 0
      Тут смысл именно в том, чтобы эмулировать отправку для спамера — чтобы он не догадался, что его вычислили.
      1. Denis Efremov 08 августа 2017, 19:22 # 0
        Покажи где я блокирую отправку.
        Я меняю стили…
    2. Павел 16 августа 2017, 18:41 # 0
      А для formit как будет?
      1. Илья Уткин 17 августа 2017, 09:22 # 0
        Для FormIt у меня готового решения нет.

      Авторизация

      через сервис Loginza:

      Подписка или RSS

      Буду присылать новые статьи — никакого спама



      Шаблоны MODX

      1 2 Дальше »

      Объектная
      модель
      MODX