Автоматизируем защиту 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 комментариев