ugrás a tartalomhoz

Küzdelem a spam ellen - újabb versenyző: whatPlus

dtaylor · 2004. Jún. 22. (K), 22.00
Küzdelem a spam ellen - újabb versenyző: whatPlus
Újra a spam elleni küzdelem a téma. Korábban Boogie bemutatta saját megoldását a weboldalakon publikált e-mail címek begyűjthetetlenné tételére. Most ugyanezt a problémát vizsgáljuk meg újra, csak egy kicsit más megközelítéssel. Az én megoldásom a korábbi cikkben bemutatott alapelvekre épül, kiegészítve és véleményem szerint leegyszerűsítve a módszereket.

A sorozatban megjelent

Célok, alapelvek

Miként a WHAT módszert bemutató cikkben is szerepel, azt kell elérnünk, hogy az oldalon megjelenő e-mail címek ne legyenek automatikusan begyűjthetőek, de ugyanakkor megmaradjanak klikkelhetőként a felhasználók számára. Annyival egyszerűsítettem a megközelítésen, hogy ne kelljen külön <div> elemeket használni a kódolt e-mail címek jelölésére, és a konverzió teljesen automatikusan működőképes legyen. Úgy érzem, elértem célomat.

Az alkalmazott technika

A speciális stílusnévvel ellátott <div> elem helyett a már meglévő <address> elemet választottam. A következőképpen fest a használt megoldással a HTML forráskód:

<address>Szabó Dénes|donci@node?subject=whatPlus</address><br />
<address>donci@node</address>
Az első esetben a link felirata a megadott szövegből képződik (| jellel elválasztva az e-mail cím előtt), a második esetben maga az e-mail cím lesz klikkelhető. Egyéb paraméterek (például subject) megadására is lehetőség van.

Megvalósítás

A megadott formátumba kódolt <address> elemek beírásával kell csak törődnöm, hiszen az összes többi hátramaradó feladatot a Smarty végzi el. Ezen sablon motort használók számára jó hír, hogy nekik csak be kell másolni a példából a kódrészletet. Aki más sablont használ, vagy saját alkalmazásába szeretné beépíteni a kódot, az kimenet buffereléssel egyszerűen adaptálhatja a megoldásomat.

Az antispam szűrő egy Smarty output plugin, azaz egy olyan beépülő komponens, mely a Smarty sablonok kimenetének előállításakor fut le. Ez egyszerűen megnézi, hogy a kész HTML lapban van-e az <address> elemek között e-mail cím. Ha van, akkor a csiga jelet kicseréli egy véletlen karaktersorozatra. Majd, ha történt csere, akkor a HTML laphoz hozzafűz egy JavaScript kódrészletet (a whatPlus() függvény az eredeti whatCorrector() alapján készült). Ez a Javascript kód felelős azért, hogy a lap letöltődésekor az e-mail címeket visszaformázza a megfelelő alakúra.

A kimeneti szűrőben figyelni kell arra, hogy a <textarea> elemek között ne történjen csere, ugyanis a DHTML szerkesztők (pl: HTMLArea) nem maradnának működőképesek, ha ott is átalakítanánk a kódot.

A módszer előnyei

  • Egyszerű. Semmivel nem kell külön törődni, elég az e-mail címeket kiírni szerkesztéskor vagy dinamikus tartalom generálásakor. Az összes megszorítás mindössze annyi, hogy az <address> elemet kell használnunk.
  • Az e-mail cím formátuma stíluslapokkal nagyon könnyen beállítható.
  • Biztonságos. A böngésző által megjelenített kódban nincs mailto:, még a JavaScript is darabokból rakja össze. A csere kód nem az állandó ##kukac## részlet, hanem letöltésről letöltésre változik.

A módszer hátrányai

  • Az itt bemutatott implementációhoz Smarty kell. Kimenet buffereléssel egyszerűen megoldható más sablon rendszerre ültetve is, ha jobb megoldás nem adódik.
  • A kimenet feldolgozás miatt valószínű, hogy tovább tart egy oldal legenerálása, mint egy Smarty plugin esetén. Tesztelők jelentkezését várom!

A Smarty kimeneti szűrő megvalósítása


<?php
function _smarty_antispam_email($tplOutput, &$smarty) {
	$splitpattern = "!(<textarea.*?/textarea>)!is";
	$newTplOutput = '';
	$changeCount = 0;
	$match = preg_split($splitpattern, $tplOutput, -1, PREG_SPLIT_DELIM_CAPTURE);
	$emailcode = md5(time( ));
	$prepattern = '!^<textarea!i';
	foreach ($match as $idx => $slice)
	{
		if (! preg_match($prepattern, $slice))
		{
			$newTplOutput .= preg_replace(
				'!(<address.*?>.*?)(\S+)@(.*?)</address>!is',
				"\${1}\${2}" . $emailcode . "\${3}" . '</address>' ,
				$slice);
			$changeCount++;
		}
		else
		{
			$newTplOutput .= $slice;
		}
	}

	if ($changeCount)
	{
		$pattern = '!</body>!i';
		$replacement = '
			<script type="text/javascript" language="javascript">
				function whatPlus() {
				var replaces = 0;
				var emailarr;
				var alltags = document.all ? document.all.tags("ADDRESS") : document.getElementsByTagName("ADDRESS");
				for (i=0; i < alltags.length; i++) {
					while (alltags[i].innerHTML.indexOf(\'' . $emailcode . '\') != -1 && replaces < 10000) {
						alltags[i].innerHTML = alltags[i].innerHTML.replace(\'' . $emailcode .'\', String.fromCharCode(64));
						emailarr = alltags[i].innerHTML.split("|");
						if (! emailarr[1])
						{
							alltags[i].innerHTML = "<a href=\"mai" + "lto:" + alltags[i].innerHTML + "\">" + alltags[i].innerHTML + "</a>";
						}
						else
						{
							alltags[i].innerHTML = "<a href=\"ma" + "ilto:" + emailarr[1] + "\">" + emailarr[0] + "</a>";
						}
						replaces++;
					}
				}
			}
			whatPlus();
			</script>
			</body>'
		;
		return preg_replace($pattern, $replacement, $newTplOutput);
	}
	return $newTplOutput;
}
?>

Alkalmazási példa


<?php
$smarty = new Smarty( );

$smarty->register_outputfilter('_smarty_antispam_email');

$smarty->assign('pageTitle', 'Auto antispam');
$smarty->display( './antispam.tpl' );
?>

Zárszó

Remélem, a módszer másoknak is megtetszik, és használni is fogják minél többen, a kód szabadon alkalmazható. A felmerülő kérdésekre, ötletekre szívesen válaszolok a hozzászólások között, vagy e-mailben.
 
1

Szerintem a legjoobb megoldas

mepet · 2004. Jún. 24. (Cs), 09.27
Szerintem a legjoobb megoldas az, ha nem irjuk ki a cimet, csak egy linket teszunk ki hogy "email" es a katt utan egy form jelenik meg, ahol az emailcim egy kep vagy flash. Mivel kell egy katt elotte, igyaztan szinte mindig eleg egy kep, de ha az oldalunkon eleve kell a flash (pl flashes menu), akkor persze ez is lehet flash is...
A latogatok 99%-a levelet akar kuldeni, es nem a cimet akarja megtudni, de ezzel a megoldassal meg a cimet is megtudhatja, ha nagyon kell neki...
Nem hiszem, h van oan spammer, aki programot irna, amelyik kattint, aztan egy kepbol kiolvassa a cimet, ha megis, akkor megerdemli azokat a cimeket :)
2

Konkrét címekre ez teljesen jó.

Bártházi András · 2004. Jún. 24. (Cs), 10.07
Amit írsz, teljesen oké egy céges weblap esetén. Egy közösségi oldalnál, levelezőlista archívumnál, vagy bárhol máshol, ahol sok ember e-mail címét kellene megjeleníteni abból a célból, hogy írhassál neki, már nem annyira jó, mivel akárhogy is nézem, kb. egy nyílt SMTP szerverhez hasonló dolgot kellene megvalósítania az oldal üzemeltetőjének. Sokkal egyszerűbb a Dénes és általam bemutatott megoldás ebben az esetben szerintem.

-boogie-
3

amit én használok:

Anonymous · 2004. Júl. 26. (H), 23.15
Én a következő, egyszerű megoldást használom, ha nem áll renddelkezésre php és társai:
A JS kód:
function spamkill(x) {
x.href=x.href.replace(/_filter1_/, "@");
x.href=x.href.replace(/_filter2_/g, ".");
return true;
}
function stat(x, vis) {
if (vis) {
window.status=x.href.replace(/_filter1_/, "@");
window.status=window.status.replace(/_filter2_/g, ".");
window.status=window.status.replace(/mailto:/, "");
} else { window.status=""; }
}

A HTML hivatkozás:
<A href="mailto:laci_filter1_domain_filter2_hu" onClick="spamkill(this)" onMouseOver="stat(this, true); return true;" onMouseOut="stat(this, false);"> EMAIL </A>


Blackfire
4

WOW

Creative · 2010. Ápr. 11. (V), 23.45
E-mail védéskor erre a megoldásra még nem is gondoltam o0 De ez jó. Saját?

C.