Trackbackspam verhindern

In letzter Zeit hatte ich, wie schonmal schonmal berichtet, vermehrt Trackbackspam. Für das Problem mit dem Kommentarspam habe ich eine gute Lösung gefunden. Seit der Einführung der Matheaufgabe, hatte ich keinen Spamkommentar mehr. Bei den Trackbacks ist das ja nicht so einfach, aber es gibt trotzdem eine recht zuverlässige Lösung.
Wenn ich von einer Seite einen Trackback erhalte, dann sollte auf dieser Seite auch ein Link auf meine Seite sein, oder sie sollte zumindest erwähnt werden. Und genau das überprüft diese Funktion.
Nun habe ich eine kleine PHP Funktiongeschrieben, welche überprüft ob auf der fremden Seite meine URL Vorkommt. So reicht eine Überprüfung des Strings t-error.ch schon. Ich muss nicht mal überprüfen, ob es ein Link ist, denn die Trackbackspammer erwähnen auf ihren Seiten meine Seite ja kaum. Die Funktion überprüft die Seite in der Variable $url und gibt die Variable $spam zurück. Relativ simpel und effektiv. Bisher wurde noch kein Trackbackspam durchgelassen.
<?
function trackbackSpamCheck($url)
{
    
// Spamvariable
    
$spam=1;

    
// die url aufsplitten
    
$parsed=parse_url(trim(addSlashes($url)));

    
// einen pfad angeben wenn noetig
    
if(!isSet($parsed['path']))
    {
        
$parsed['path']="/";
    }

    
// den querystring anfuegen wenn noetig
    
$path=$parsed['path'];
    if(isSet(
$parsed['query']))
    {
        
$path.="?".$parsed['query'];
    }

    
// zum host verbinden
    
$fp=fSockOpen($parsed['host'],80,$errno,$errstr,30);
    if(
$fp)
    {
        
// GET request senden
        
fPuts($fp,"GET ".$path." HTTP/1.0\r\n");
        
fPuts($fp,"Host: ".$parsed['host']."\r\n\r\n");

        
// Den Quelltext auslesen
        
while(!fEof($fp))
        {
            
// auf t-error.ch pruefen
            
if(eregi("t-error.ch",fgets($fp,1024)))
            {
                
// wenn vorhanden $spam auf 0 setzen und abbrechen
                
$spam=0;
                break;
            }
        }

        
// verbindung trennen
        
fclose($fp);
    }
    
    return 
$spam
}
?>

Autokompletierung abschalten

Die autovervollständigen Funktionen der heutigen Browser sind ja schon schöne Sachen. Nur den ersten Buchstaben eintippen und schon werden schon benutzte Texte angezeigt. Manchmal möchte man das allerdings nicht. Zum Beispiel bei Ajax-Suchen wo die Vorschläge von eine Script zur Verfügung gestellt werden. Wenn nun der Browser auch noch seine Vorschläge anzeigt, kommt das zu hässlichen Überschneidungen.
Mit JavaScript kann man diese Funktion relativ simpel für bestimmt Textfelder deaktvieren. Die Methode setAttribute() macht das möglich. Zuerst schreibt man eine kleine Funktion, die entweder direkt in den Head oder halt in eine externe Datei eingebunden wird. Eine externe Datei hat en Vorteil, dass sie weniger Traffic verursacht, da sie gecacht werden kann.
function disableAutocompletion()
{
    var autocomplete=document.getElementById('user');
    if(autocomplete==null) return;
    autocomplete.setAttribute('autocomplete','off');
}

Diese Funktion wird nun via onLoad() beim Laden der Seite aufgerufen.
<body onLoad="disableAutocompletion()">

Und schon werden vom Browser keine Vorschläge mehr gemacht.

Update, 22.03.07 09:49:
Warum einfach wenns auch kompliziert geht. Mit autocomplete="off" direkt im Input-Feld lässt sich das auch abstellen.

Update 2, 22.03.07 10:24:
autocomplete scheint allerdings kein Valides XHTML Attribut zu sein.

Ajaxing

Für eine kleine Webapplikation im Geschäft, die wir verwenden werden um die Flugtarife zu verwalten, arbeite ich mich nun in Ajax ein. Ich war erstaunt wie einfach das war. Eine übersicht an Ajax Tutorial gibt bei Dr. Web. Ich habe mir die kürzeste Version rausgepickt und das ganze auf meine Bedürfnisse angepasst.
Als erstes benötigt man ein Objekt, mit dem man die Daten sendet bzw. empfängt. Dies sieht so aus:
function createRequestObject()
{
    var ro;
    var browser=navigator.appName;
    if(browser=="Microsoft Internet Explorer")
    {
        ro=new ActiveXObject("Microsoft.XMLHTTP");
    }
    else
    {
        ro=new XMLHttpRequest();
    }
    return ro;
}

var http=createRequestObject();

Um nun die Daten zu senden benötigt man eine weitere Funktion. Hier sendReq genannt:
function sendReq(url)
{
    http.open('get',url);
    http.onreadystatechange = handleResponse;
    http.send(null);
}

Diese Funktion sendet einen GET Request an die per Parameter übergebene URL. Danach wird die Funktion handleResponse() aufgerufen, welche die Daten verarbeitet.
function handleResponse()
{
    if(http.readyState == 4)
    {
        var response=http.responseText;
        document.getElementById('showData').innerHTML=response;
    }
}

Diese überprüft zuerst, ob die Übermittlung vollständig ist und schreibt die Daten dann in den div Container mit der ID showData. Hier die verschieden Werte und deren Bedeutung die http.readystate haben kann.
	0 = uninitialized
	1 = loading
	2 = loaded
	3 = interactive
	4 = complete

Diese funktionen werden aber nicht direkt aus der HTML-Seite aufgerufen. Ich habe dafür eine kleine Wrapperfunktion gebaut, die das ganze einwenig übersichtlicher macht.
function flights()
{
    var airline=document.filter.airline.value;
    var destination=document.filter.destination.value;
    var date=document.filter.date.value;
    var class=document.filter.class.value;

    sendReq('rpc.php?action=flights&airline='+airline+'&destination='+destination+'&date='+date+'&class='+class);
}

Wird nun also die Funktion flights() von der HTML-Seite aufgerufen, so liest das Script die Werte der Input-Felder airline, destination, date und class aus. Diese Daten werden mit einem GET Request an das PHP-Script rpc.php weitergegeben. Nach der Verarbeitung der Daten gibt das PHP-Script die Daten aus und die JS-Funktion schreibt sie in den Div-Container. Eigentlich recht simpel und es verweinfacht die Arbeit mit der Applikation merklich.

Mail -> Blog

Ich arbeite momentan an einem kleinen PHP Script, welches Mails von einem bestimmten Konto ausliest und als Artikel auf meine Homepage schreibt.
Dadurch kann ich auch unter der Woche einen kleinen Statusbericht durchgeben. Ich denke, es ist auch möglich noch eine Unterstützung für Bilder zu erstellen. Dann kann ich Bilder von meinem Handy direkt per Mail auf die Homepage stellen.

Noch genauer zur Funktion:
Zuerst schreibe ich ein Mail an eine vorher definierte E-Mail adresse.
Auf der ersten Zeile steht ein Passwort. Schliesslich soll ja nicht jeder in meinem Blog schreiben können.
Auf der zweiten Zeile ist eine Komma getrennt Liste der Topics, zu welchen der Artikel gehört.
Danach kommt der Text
Der Titel des Artikels wird aus dem Betreff gelesen

Das PHP Script wir immer wieder vom cron aufgerufen und überprüft, ob im Mailkonto neue Nachrichten vorhanden sind.
Ist dies der fall, werden die Nachrichten heruntergeladen und ausgewertet. Das heisst, auslesen und überprüfen des Passwortes, auslesen von Datum, Titel, Text und die Topics.
Nun muss der Artikel nur noch in die DB geschrieben werden. Keine wirkliche Hexerei :)

Vieleicht werde ich heute noch damit fertig. Spätestens aber nächstes Weekend. Da ist ja Ostern und ich habe viel mehr Zeit.