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:
  1. <address>Szabó Dénes|donci@node?subject=whatPlus</address><br />  
  2. <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

  1. <?php  
  2. function _smarty_antispam_email($tplOutput, &$smarty) {  
  3.     $splitpattern = "!(<textarea.*?/textarea>)!is";  
  4.     $newTplOutput = '';  
  5.     $changeCount = 0;  
  6.     $match = preg_split($splitpattern$tplOutput, -1, PREG_SPLIT_DELIM_CAPTURE);  
  7.     $emailcode = md5(time( ));  
  8.     $prepattern = '!^<textarea!i';  
  9.     foreach ($match as $idx => $slice)  
  10.     {  
  11.         if (! preg_match($prepattern$slice))  
  12.         {  
  13.             $newTplOutput .= preg_replace(  
  14.                 '!(<address.*?>.*?)(\S+)@(.*?)</address>!is',  
  15.                 "\${1}\${2}" . $emailcode . "\${3}" . '</address>' ,  
  16.                 $slice);  
  17.             $changeCount++;  
  18.         }  
  19.         else  
  20.         {  
  21.             $newTplOutput .= $slice;  
  22.         }  
  23.     }  
  24.   
  25.     if ($changeCount)  
  26.     {  
  27.         $pattern = '!</body>!i';  
  28.         $replacement = '  
  29.             <script type="text/javascript" language="javascript">  
  30.                 function whatPlus() {  
  31.                 var replaces = 0;  
  32.                 var emailarr;  
  33.                 var alltags = document.all ? document.all.tags("ADDRESS") : document.getElementsByTagName("ADDRESS");  
  34.                 for (i=0; i < alltags.length; i++) {  
  35.                     while (alltags[i].innerHTML.indexOf(\'' . $emailcode . '\') != -1 && replaces < 10000) {  
  36.                         alltags[i].innerHTML = alltags[i].innerHTML.replace(\'' . $emailcode .'\', String.fromCharCode(64));  
  37.                         emailarr = alltags[i].innerHTML.split("|");  
  38.                         if (! emailarr[1])  
  39.                         {  
  40.                             alltags[i].innerHTML = "<a href=\"mai" + "lto:" + alltags[i].innerHTML + "\">" + alltags[i].innerHTML + "</a>";  
  41.                         }  
  42.                         else  
  43.                         {  
  44.                             alltags[i].innerHTML = "<a href=\"ma" + "ilto:" + emailarr[1] + "\">" + emailarr[0] + "</a>";  
  45.                         }  
  46.                         replaces++;  
  47.                     }  
  48.                 }  
  49.             }  
  50.             whatPlus();  
  51.             </script>  
  52.             </body>'  
  53.         ;  
  54.         return preg_replace($pattern$replacement$newTplOutput);  
  55.     }  
  56.     return $newTplOutput;  
  57. }  
  58. ?>  

Alkalmazási példa

  1. <?php  
  2. $smarty = new Smarty( );  
  3.   
  4. $smarty->register_outputfilter('_smarty_antispam_email');  
  5.   
  6. $smarty->assign('pageTitle''Auto antispam');  
  7. $smarty->display( './antispam.tpl' );  
  8. ?>  

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.