Автоматизируем защиту e-mail адресов от спамеров
Как уже многие знают, одним из методов получения базы e-mail адресов для спам-рассылок является обход сайтов роботами спамеров в поисках адресов.
Предотвратить это можно простым способом: закодировать e-mail адреса на странице так, чтобы для пользователя всё отображалось в обычном виде, но в исходном коде в открытом виде адресов не было. Об этом уже много чего написано и есть хорошая статья на хабре: habrahabr.ru/post/22549/
Далее рассмотрим, как можно автоматизировать процесс кодирования, чтобы на всех страницах e-mail адреса были всегда закодированы.
Суть метода состоит в поиске всех адресов с помощью регулярных выражений и их кодирования тем или иным способом. В настоящее время мы у себя используем кодирование адресов с помощью JavaScript.
а) адрес находится в качестве атрибута парного тега;
б) в качестве атрибута одиночного тега;
в) в качестве текста вне тегов.
Для всех этих вариантов написаны специальные регулярные выражения, которые отправляют найденные адреса на кодирование.
Найденные совпадения перебираем и кодируем. Например так:
Нюансы:
1. Это не будет работать если e-mail адреса находятся в JavaScript блоке. Но на своей практике пока такого не встречал.
2. Это можно применить если движком сайта можно получить исходный код сгенерированной страницы.
Например, на yii это можно организовать в методе контроллера processOutput:
Исходники: github.com/cvek/EncodeEmail
Предотвратить это можно простым способом: закодировать e-mail адреса на странице так, чтобы для пользователя всё отображалось в обычном виде, но в исходном коде в открытом виде адресов не было. Об этом уже много чего написано и есть хорошая статья на хабре: habrahabr.ru/post/22549/
Далее рассмотрим, как можно автоматизировать процесс кодирования, чтобы на всех страницах e-mail адреса были всегда закодированы.
Суть метода состоит в поиске всех адресов с помощью регулярных выражений и их кодирования тем или иным способом. В настоящее время мы у себя используем кодирование адресов с помощью JavaScript.
Копнем исходники
Разберем часть исходного кода. Сначала мы ищем все адреса. Для этого мы рассматриваем несколько вариантов:а) адрес находится в качестве атрибута парного тега;
б) в качестве атрибута одиночного тега;
в) в качестве текста вне тегов.
Для всех этих вариантов написаны специальные регулярные выражения, которые отправляют найденные адреса на кодирование.
<code class="php"> $tags = array("a", "area"); // 1 вариант - теги закрыты: <a>...</a> preg_match_all("/\<(".implode("|", $tags).")\s{1}([^<]*?)href=[\'|\"]mailto\:(".self::getMailPattern(false, false).")[\'|\"]{1}([^\>]*)\>(.*?)\<\/(".implode("|", $tags).")\>/iu", $htmlSrc, $matches, PREG_SET_ORDER); $htmlSrc = self::processMatchesEmail($htmlSrc, $matches); // Разновидность 1 варианта - на случай, если теги не закрыты preg_match_all("/\<(".implode("|", $tags).")\s{1}([^<]*?)href=[\'|\"]mailto\:(".self::getMailPattern(false, false).")[\'|\"]{1}([^\>\/]*)\>/i", $htmlSrc, $matches, PREG_SET_ORDER); $htmlSrc = self::processMatchesEmail($htmlSrc, $matches); // 2 вариант - теги пустые, но закрыты: <area /> preg_match_all("/\<(".implode("|", $tags).")\s{1}([^<]*?)href=[\'|\"]mailto\:(".self::getMailPattern(false, false).")[\'|\"]{1}([^\>]*)\/\>/i", $htmlSrc, $matches, PREG_SET_ORDER); $htmlSrc = self::processMatchesEmail($htmlSrc, $matches); // 3 вариант - mail вне тегов. $htmlSrc = self::processEmailInText($htmlSrc); </code>
Найденные совпадения перебираем и кодируем. Например так:
<code class="php"> public static function getJsEmail($mail) { $len = strlen($mail); $res = ''; for ($i = 0; $i < $len; $i++) { $char = $mail{$i}; if ($char == '@') { $res .= "' + '&' + '#6' + '4;' + '"; } else { if ($i % 2 == 0) { $res .= htmlentities($char, ENT_QUOTES, 'utf-8'); } else { $res .= $char; } } } $res = "'".$res."'"; return $res; } </code>
Нюансы:
1. Это не будет работать если e-mail адреса находятся в JavaScript блоке. Но на своей практике пока такого не встречал.
2. Это можно применить если движком сайта можно получить исходный код сгенерированной страницы.
Например, на yii это можно организовать в методе контроллера processOutput:
<code class="php"> public function processOutput($output) { $output = parent::processOutput($output); return HEmailEncode::encodeHtmlSource($output); } </code>3. Желательно организовать кэширование страниц, обработанных с помощью этой штуки, чтобы на каждый хит не было однообразной работы. В таком случае, кодировать надо html у кэшируемых блоков, а в шаблоне страницы адреса закодировать вручную:
<code class="php">echo HEmailEncode::getJsEmailEx('test@test.ru'); </code>Но на небольших сайтах можно и забить.
Исходники: github.com/cvek/EncodeEmail
0 комментариев