Анти-спам или как на странице сайта скрыть код формы от ботов?

Анти-спам или как на странице сайта скрыть код формы от ботов?
Анти-спам или как на странице сайта скрыть код формы от ботов?

Не ошибусь, если скажу, что практически все владельцы сайтов сталкиваются с такой проблемой, как СПАМ. Это просто кошмар, когда ваш почтовый ящик ежедневно наполняется сотнями, а то и тысячами СПАМ-писем. В таком объёме мусорной корреспонденции очень легко потерять и даже удалить нужную и важную информацию или заказ. При этом, практически ничего не помогает избавиться от ботов назойливых спамеров. Использование обычной каптчи и reCaptcha от Google не помогает, не помогают и  различные "фишки", которые рассчитаны на использование javascript. Хотя боты и научились выполнять код Javascript, в подавляющем большинстве случаев они ищут на странице тег <form>. Вот эту их особенность мы и будем использовать.

Я не буду в этой остатье освещать тему, что нужно создавать разные почтовые ящики для обычных заявок и заказов магазина, не показывая эту почту на сайте и более нигде в интернете, ну и т.д. Я хочу сейчас предложить идею, как скрыть форму от ботов для владельцев сайтов на HostCMS. На других CMS такое тоже возможно, а может быть уже где-то и реализовано. Идея мной уже опробована на сайтах клиентов и работает на 100%. С помощью этого решения форму можно подгружать на любую страницу и это может быть "Заказ обратного звонка", "Форма заявки" и любая другая форма коммуникации с Пользователем. Данное решение возможно использовать только на платных версиях, начиная с HostCMS Малый Бизнес, где есть нужный нам модуль "Формы". Для бесплатных версий не делалось.

Поскольку сама интеграция решения является платной услугой, то я опишу только теоретическую часть. Программистам не сложно будет самим реализовать эту идею. Запросить подробное описание с кодом или сделать заявку на реализацию этого решения на вашем сайте можно через форму обратной связи. Предвосхищая вопросы скажу, что для себя это решение пока не использовали в виду отсутствия спама от ботов. От спамеров, работающих "ручками" оно, естественно, не поможет.

Итак перейдём к делу. Как же сделать так, чтобы кода формы не было в дереве DOM после загрузки страницы и она бы подгружалась только тогда, когда её "вызовет" Пользователь, например, кликом на соответствующую кнопку. Пошагово:

1. Создадим узел структуры и назовём его, например, "Обратная связь" (путь условно - /form/). Подключим к структуре стандартный ТДС "Отображение формы" и XSL-шаблоны. В самое начало кода настроек ТДС добавляется обработчик, который на ajax загружает форму в момент обращения к ней. Фрагмент кода:

if (Core_Array::getRequest('openForm') == "1")
{
ob_start();
.... echo json_encode(ob_get_clean());
exit();
}

2. Поскольку форма у нас будет подгружаться в модальном окне, немного доработаем стандартный XSL-шаблон "Отобразить форму". Для показа модального окна воспользуемся библиотекой Bootstrap (если не используете эту библиотеку, то можете добавить стили и скрипт для создания своих модальных окон) и добавим соответствующие теги. Для показа ответа сервера, в случае ошибки или удачной отправки формы, я не стал использовать Bootstrap, а просто добавил немного стилей и несколько строк jQuery. Вы можете усовершенствовать моё решение и использовать только Bootstrap, например. 

Свой вариант XSL шаблона привожу полностью:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:hostcms="http://www.hostcms.ru/"
exclude-result-prefixes="hostcms">
<xsl:output xmlns="http://www.w3.org/TR/xhtml1/strict" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" encoding="utf-8" indent="yes" method="html" omit-xml-declaration="no" version="1.0" media-type="text/xml" />
<!-- ОтобразитьФорму -->
<xsl:template match="/">
<xsl:apply-templates select="/form" />
</xsl:template>
<xsl:template match="/form">
<xsl:choose>
<xsl:when test="success/node() and success = 1">
<div id="fade" style="display: block;"></div>
<div class="modal-message form-success-result">
<div class="modal-content">
<div class="modal-header text-center"><button class="close" type="button" data-dismiss="modal"></button>
<h5 class="modal-title">Спасибо! <br /> Ваша заявка принята.</h5>
</div>
<div class="box-content text-center">
<div class="margin-bottom-10">Мы свяжемся с вами в ближайшее время</div>
</div>
</div>
</div>
</xsl:when>
<!-- Выводим ошибку (error), если она была передана через внешний параметр -->
<xsl:when test="error != ''">
<div id="fade" style="display: block;"></div>
<div class="modal-message">
<div class="modal-content">
<div class="modal-header text-center"><button class="close" type="button" data-dismiss="modal"></button>
<h4 class="modal-title">ОШИБКА!</h4>
</div>
<div class="box-content text-center"><b><xsl:value-of disable-output-escaping="yes" select="error" /></b></div>
</div>
</div>
</xsl:when>
<xsl:when test="errorId/node()">
<div id="fade" style="display: block;"></div>
<div class="modal-message">
<div class="modal-content">
<div class="modal-header text-center"><button class="close" type="button" data-dismiss="modal"></button>
<h4 class="modal-title">ОШИБКА!</h4>
</div>
<div class="box-content text-center">
<xsl:choose>
<xsl:when test="errorId = 0">
Вы неверно ввели число подтверждения отправки формы!
</xsl:when>
<xsl:when test="errorId = 1">
Заполните все обязательные поля!
</xsl:when>
<xsl:when test="errorId = 2">
Прошло слишком мало времени с момента последней отправки Вами формы!
</xsl:when>
</xsl:choose>
</div>
</div>
</div>
</xsl:when>
<xsl:otherwise>
<!-- Проверка формы -->
<SCRIPT>
$(function() {
var myForm<xsl:value-of select="/form/@id" /> = $("#form<xsl:value-of select="/form/@id" />");
$(myForm<xsl:value-of select="/form/@id" />).validate({
focusInvalid: true,
errorClass: "input_error",
onkeyup: false,
onfocusout: false,
rules: {
name: "required",
phone: "required",
email: {
required: true,
email: true
}
},
messages: {
name: "Это поле не заполнено",
phone: "Это поле не заполнено",
email: {
required: "Введите свой email",
email: "E-mail должен быть в формате name@domain.com"
}
}});
});
</SCRIPT>
<div class="modal fade" id="zayavkaModal_{@id}" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal"></button>
<h4 class="modal-title"><xsl:value-of disable-output-escaping="yes" select="name" /></h4>
<p> Наш менеджер ответит вам в самое ближайшее время </p>
<xsl:value-of disable-output-escaping="yes" select="description" />
<div class="note margin-top-10"><sup>*</sup> поля, обязательные для заполнения</div>
</div>
<div class="modal-body">
<!-- Параметр action формы должен быть "./", если обработчик на этой же странице, либо "./form/", если обработчик на другой странице, например ./form/ -->
<form name="form{@id}" id="form{@id}" class="validate fast_form" action="./" method="post" enctype="multipart/form-data" >
<div class="row">
<!-- Вывод разделов формы 0-го уровня -->
<xsl:apply-templates select="form_field_dir" />
<!-- Вывод списка полей формы 0-го уровня -->
<xsl:apply-templates select="form_field" />
</div>

<div class="row form-group">
<div class="small margin-bottom-20">
<input id="checkbox{@id}" type="checkbox" name="checkbox" checked="checked" onchange="document.getElementById('submit_{@id}').disabled = !this.checked;"/>
<label for="checkbox{@id}"><span class="grey">Отправляя Заявку, я даю согласие на обработку своих персональных данных, согласно <a href="/private"> Политики конфиденциальности</a></span></label>
</div>
<input type="hidden" name="{button_name}" value="submit"/>
<button id="submit_{@id}" value="submit" name="{button_name}_submit" type="submit" class="btn btn-primary full-width">Отправить</button>
</div>
</form>
</div>
</div>
</div>
</div>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="form_field_dir">
<!--fieldset class="maillist_fieldset"-->
<!--legend><xsl:value-of select="name" /></legend-->
<!-- Вывод списка полей формы -->
<xsl:apply-templates select="form_field" />
<!-- Вывод разделов формы -->
<xsl:apply-templates select="form_field_dir" />
<!--/fieldset-->
</xsl:template>
<xsl:template match="form_field">
<!-- Не скрытое поле и не надпись -->
<xsl:if test="type != 7 and type != 8">
<xsl:if test="type != 5">
<div class="form-group">
<!-- Текстовые поля -->
<xsl:if test="type = 0 or type = 1 or type = 2">
<input type="text" name="{name}" value="{value}" size="{size}" placeholder="{caption}" class="form-control">
<xsl:choose>
<!-- Поле для ввода пароля -->
<xsl:when test="type = 1">
<xsl:attribute name="type">password</xsl:attribute>
</xsl:when>
<!-- Поле загрузки файла -->
<xsl:when test="type = 2">
<xsl:attribute name="type">file</xsl:attribute>
</xsl:when>
<!-- Текстовое поле -->
<xsl:otherwise>
<xsl:attribute name="type">text</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="obligatory = 1">
<xsl:attribute name="class">form-control required</xsl:attribute>
<xsl:attribute name="minlength">1</xsl:attribute>
<xsl:attribute name="title">Заполните поле <xsl:value-of disable-output-escaping="yes" select="caption" /></xsl:attribute>
</xsl:if>
</input>
</xsl:if>
<!-- Радиокнопки -->
<xsl:if test="type = 3 or type = 9">
<xsl:apply-templates select="list/list_item" />
<label class="input_error" for="{name}" style="display: none">Выберите, пожалуйста, значение.</label>
</xsl:if>
<!-- Checkbox -->
<xsl:if test="type = 4">
<input type="checkbox" name="{name}">
<xsl:if test="checked = 1 or value = 1">
<xsl:attribute name="checked">checked</xsl:attribute>
</xsl:if>
</input>
</xsl:if>
<!-- Список -->
<xsl:if test="type = 6">
<select name="{name}">
<xsl:if test="obligatory = 1">
<xsl:attribute name="class">required</xsl:attribute>
<xsl:attribute name="title">Заполните поле <xsl:value-of disable-output-escaping="yes" select="caption" /></xsl:attribute>
</xsl:if>
<option value="">...</option>
<xsl:apply-templates select="list/list_item" />
</select>
</xsl:if>
</div>
</xsl:if>
<!-- Textarea -->
<xsl:if test="type = 5">
<div class="form-group">
<textarea name="{name}" cols="{cols}" rows="{rows}" wrap="off" class="form-control" placeholder="{caption}">
<xsl:if test="obligatory = 1">
<xsl:attribute name="class">form-control required</xsl:attribute>
<xsl:attribute name="minlength">1</xsl:attribute>
<xsl:attribute name="title">Заполните поле <xsl:value-of disable-output-escaping="yes" select="caption" /></xsl:attribute>
</xsl:if>
<xsl:value-of select="value" />
</textarea>
</div>
</xsl:if>
</xsl:if>
<!-- скрытое поле -->
<xsl:if test="type = 7">
<input type="hidden" name="{name}" value="{value}" />
</xsl:if>
<!-- Надпись -->
<xsl:if test="type = 8">
<div class="form-group">
<div id="{name}" class="field white">
<strong><xsl:value-of disable-output-escaping="yes" select="caption" />:</strong> <span></span>
</div>
</div>
</xsl:if>
</xsl:template>
<!-- Формируем радиогруппу или выпадающий список -->
<xsl:template match="list/list_item">
<xsl:choose>
<xsl:when test="../../type = 3">
<input id="{../../name}_{@id}" type="radio" name="{../../name}" value="{value}">
<xsl:if test="value = ../../value">
<xsl:attribute name="checked">checked</xsl:attribute>
</xsl:if>
<xsl:if test="../../obligatory = 1">
<xsl:attribute name="class">required</xsl:attribute>
<xsl:attribute name="minlength">1</xsl:attribute>
<xsl:attribute name="title">Заполните поле <xsl:value-of disable-output-escaping="yes" select="caption" /></xsl:attribute>
</xsl:if>
</input><xsl:text> </xsl:text>
<label for="{../../name}_{@id}"><xsl:value-of disable-output-escaping="yes" select="value" /></label>
<br/>
</xsl:when>
<xsl:when test="../../type = 6">
<option value="{value}">
<xsl:if test="value = ../../value">
<xsl:attribute name="selected">selected</xsl:attribute>
</xsl:if>
<xsl:value-of disable-output-escaping="yes" select="value" />
</option>
</xsl:when>
<xsl:when test="../../type = 9">
<xsl:variable name="currentValue" select="@id" />
<input id="{../../name}_{@id}" type="checkbox" name="{../../name}_{@id}" value="{value}">
<xsl:if test="../../values[value=$currentValue]/node()">
<xsl:attribute name="checked">checked</xsl:attribute>
</xsl:if>
<xsl:if test="../../obligatory = 1">
<xsl:attribute name="class">required</xsl:attribute>
<xsl:attribute name="minlength">1</xsl:attribute>
<xsl:attribute name="title">Заполните поле <xsl:value-of disable-output-escaping="yes" select="caption" /></xsl:attribute>
</xsl:if>
</input><xsl:text> </xsl:text>
<label for="{../../name}_{@id}"><xsl:value-of disable-output-escaping="yes" select="value" /></label>
<br/>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

CSS стили для показа модального окна при ошибках отправки или подтверждения:

.modal-message {
height: 325px;
width: 360px;
position: fixed;
opacity: 1;
overflow: visible;
left: 50%;
z-index: 1101;
vertical-align: middle;
top: 100px;
margin-left: -180px;
display: block;
color: #fff;
}
.modal-message .modal-content {
border-radius: 0;
box-shadow: 0 0 12px rgba(0,0,0,0.2);
position: relative !important;
width: 100%;
max-width: 500px !important;
background-color:#fff;
border: 0;
padding: 45px;
margin: 3% auto !important;
color: #666;
}
.modal-header {
padding: 20px 30px 0;
margin-bottom: 10px;
border:0;
} #fade {
background: #000000;
background: transparent;
background: rgba(0,0,0,0.4);
display: none;
height: 100%;
left: 0;
position: fixed;
top: 0;
width: 100%;
z-index: 1100;
}

И немного jQuery, чтобы закрыть это модальное окно:

$('body').click('#fade', function() {
$('.modal-message, #fade').hide();
$('.modal-message, #fade').remove();
});
$('body').click('.modal-message .close', function() {
$('#fade').hide();
$('#fade').remove();
var message = $(this).closest('.modal-message');
message.hide();
message.remove();
});

3. В Основной макет сайта, во вкладку JS, добавляем функцию openForm, которая у нас будет отслеживать клик по кнопке и отправлять запрос к созданному в п.1 узлу структуры с формой. В ответе мы как раз и получим код формы.

// Функции без создания коллекции
$.extend({
// Загрузка форм заявок на ajax
openForm: function(path, form_id, item_name, mess) {
... return false; }); } });
4. И сама кнопка, которая вызовет функцию openForm:
<button class="btn btn-secondary" type="button" onclick="return $.openForm('/form/', 1,)">Заказать звонок</button>

В параметрах функции указыаем путь к узлу структуры с обработчиком и ID формы, которую нам нужно загрузить на страницу и которая созданна в модуле "Формы". На одной странице может быть несколько кнопок для вызова одной и той же формы или разных форм. Меняется только ID формы.

На этом всё. Если вам нужно реализовать это решение на своём сайте, пишите в чат на сайте или через форму обратной связи.

Понравилась статья?
Будем признательны, если поделитесь в соцсетях или мессенджерах, а также присоединитесь к нашей группе Вконтакте. Будет интересно!

Вас может заинтересовать:

HOSTCMS v.6. Полезные php коды
HOSTCMS v.6. Полезные php коды
Некоторые полезные php коды для вывода данных на странице сайта.

HOSTCMS v.6. Проверка вводимых данных при оформлении заказа
HOSTCMS v.6. Проверка вводимых данных при оформлении заказа
В 6 версии разработчики убрали проверку вводимых данных в форму заказа на шаге заполнения адреса доставки. Предлагаю очень простое решение этой проблемы с использованием JavaScript. 

HOSTCMS v.6. Боковое выпадающее меню на CSS для каталога товаров
HOSTCMS v.6. Боковое выпадающее меню на CSS для каталога товаров
Создадим раздвижное меню для каталога товаров с несколькими уровнями вложенности разделов. Меню будет открыто в основных разделах, лежащих в корневом каталоге. В принципе, вам нужно просто скопировать шаблон, CSS стили и пользоваться этим меню...

HOSTCMS v.6. Поиск по сайту с показом карточки товара
HOSTCMS v.6. Поиск по сайту с показом карточки товара
Небольшая доработка стандартного XSL шаблона «Поиск» для сайтов на HostCMS

HOSTCMS v.6. Красивое горизонтальное выпадающее меню на CSS
HOSTCMS v.6. Красивое горизонтальное выпадающее меню на CSS
Меню адаптированно к использованию на сайтах под администрированием редакции HostCMS v.5 для вывода элементов каталога товаров. В выпадающем меню также выводится изображение подгруппы.

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

Мы используем файлы cookie. Они помогают улучшить ваше взаимодействие с сайтом.