Einen HttpRequest mittels Javascript erzeugen
Veröffentlicht am 30.05.2007 | Kommentar schreiben | Tags: html, javascript, ajax
In letzter Zeit ist Ajax in aller Munde und so mancher fragt sich, was es damit eigentlich auf sich hat. Ich möchte in diesem Artikel kurz auf den Kernpunk von Ajax eingehen und beschreiben, wie man einen HttpRequest mittels Javascript erzeugen kann.
Ajax bedeutet ausgeschrieben Asynchronous Javascript and XML und bedient sich der Programmiersprache Javascript. Ajax ist wie man meinen könnte keine eigene Programmiersprache sondern es bezeichnet ein Konzept der asynchronen Datenübertragung.
Dieses Konzept ermöglicht es, innerhalb einer HTML-Seite eine HTTP-Anfrage durchzuführen, ohne die Seite komplett neu laden zu müssen. Das kann bei sehr großen und aufwendigen Webseiten zu enormen Einsparungen an Ressourcen (Rechen- bzw. Ladezeit) führen. Vergleichbar ist dieses Konzept mit einem Frame, bei einem Seitenaufruf wird nur der Frame neu geladen.
Im Folgenden nun ein Beispielcode einer Webseite. Diese Webseite setzt sich zusammen aus einer HTML-, Javascript- und einer PHP-Datei.
HTML Datei (index.html):
<html> <head> <title>HttpRequest</title> <script type="text/javascript" src="javascript.js"></script> </head> <body> <a href="#" id="link">Starte HttpRequest</a> <div id="ergebnis"></div> </body> </html>
PHP Datei (httprequest.php):
<?php echo "Dies ist der übergebene Text"; ?>
Javascript Datei (javascript.js):
function $(id) { return document.getElementById(id); } window.onload = function() { $('link').onclick = function() { getHttpRequest(); return false; } } function getHttpRequest() { var xmlhttp = null; // Mozilla if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); } // IE else if (window.ActiveXObject) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("GET", 'httprequest.php', true); xmlhttp.onreadystatechange = function() { if(xmlhttp.readyState != 4) { $('ergebnis').innerHTML = 'Seite wird geladen ...'; } if(xmlhttp.readyState == 4 && xmlhttp.status == 200) { $('ergebnis').innerHTML = xmlhttp.responseText; } } xmlhttp.send(null); }
Erklärung zum Aufbaus:
In der HTML Datei (index.html) wird im head-Bereich zunächst die benötigte Javascript Datei (javascript.js) eingebunden. Der Link und der Div-Container sind mit einer ID versehen, damit per Javascript direkt auf diese Objekte zugegriffen werden kann.
Die PHP Datei (httprequest.php) sieht vor, einen einfachen Text auszugeben. Dies ist nur ein sehr einfaches Beispiel, daher wird auf komplizierten Code weitesgehend verzichtet.
In der Javascript Datei (javascript.js) wird zunächst die Funktion function $(id) {} implementiert. Diese ersetzt den langen Ausdruck document.getElementById() und macht das Arbeiten somit ein wenig bequemer. In der window.onload Anweisung wird dem Link, in dem Fall mit der ID link, ein onclick-Ereignis zugeschrieben. Wenn also auf den Link mit der ID link geklickt wird, soll die Funktion getHttpRequest() aufgerufen werden.
Erklärung zur Funktion getHttpRequest():
Die erste if-Abfrage prüft, ob es sich beim verwendeten Browser um einen Mozilla- oder einen Microsoftbrowser handelt. Diese Browser verwenden für die Erstellung eines XMLHttp-Objektes jeweils eine andere Funktion.
Die Funktion open, stellt eine Anfrage an die Datei httprequest.php. Die Funktion onreadystatechange prüft nun den Status der Verarbeitung der Datei. Hat der Status den Wert 4, bedeutet das, dass die Antwort des Servers vollständig empfangen wurde und dass sie nun bearbeitet werden kann.
Folgende Stati können auftreten:
- 0 (nicht initialisiert)
- 1 (lade)
- 2 (geladen)
- 3 (interaktiv)
- 4 (vollständig)
Tritt nun der Fall 4 ein, wird mit der Anweisung $('result').innerHTML = xmlhttp.responseText das Ergebnis der Anfrage in den Div-Container mit der ID ergebnis geschrieben.
Probleme mit Umlauten
Bei der Übertragung von Sonderzeichen oder Umlauten zwischen PHP und JavaScript und umgekehrt kann es zum Verlust von Zeichen kommen, da JavaScript in UTF8 arbeitet.
Um dieses Problem zu umgehen stehen in PHP und JavaScript diverse Funktionen zur Verfügung, um den String umzuwandeln.
Um von PHP nach JavaScript einen Sting verlustfrei übertragen zu können wird im PHP-Skript der String mit der Funktion urlencode() kodiert. In JavaScript-Skript muss dieser dann mit unescape() wieder dekodiert werden. Anders herum geht's mit den Funktionen escape() und urldecode().
Leerzeichen
PHP- und JavaScript-Funktionen wandeln das Leerzeichen unterschiedlich um. PHP macht aus einem Leerzeichen ein +, JavaScript hingegen wandelt ein Leerzeichen in ein %20 um.
Eine entsprechende Funktion könnte folgende sein:
function unescape_complete(Ersetzen) { Ersetzen = Ersetzen.split('+').join('%20'); return unescape(Ersetzen); }
[Danke an Adrian]
Cache-Problem
Bei manchen Browsern kann es vorkommen, dass die über Javascript abgerufene PHP Datei in den Cache aufgenommen wird. Dadurch wird unter Umständen nicht eine aktuelle Ausgabe zurückgegeben, sondern eine veraltete. Um dies zu verhindern, kann man der Datei einen dynamischen Parameter mitgeben, der sich immer verändert und somit der Dateiaufruf sich niemals ähnelt.
xmlhttp.open("GET", 'httprequest.php?date=' + new Date().getTime(), true);
[Danke an reimar]
Wenn du die Prototype-Utility Methode
$('ergebnis').innerHTML = 'Seite wird geladen ...';
benutzt, dann kannste doch auch gleich noch die AJAX-Funktion von Prototype benutzen ;)
Hallo Jurik,
es ging hier nicht um die Vorstellung eines Javascript-Frameworks sondern um das Grundverständis von einer HTTP-Request.
Gruß Christian
Ein super Artikel, sowas hab ich schon ewig gesucht... ;)
Sehr schöner Artikel. Er hat mir geholfen in die Materie einzusteigen.
Aber vielleicht hat Jemand eine Idee, wie man das Umlaut/Sonderzeichen Problem in den Griff bekommen kann.
MfG
Adrian
@Adrian
Du kannst auf PHP-Seite die Funktion urlencode() benutzen um den zu übertragenen String in ein Format zu bringen, in dem keine Zeichen kaputt gehen können.
Auf JavaScript Seite kanns du dann mit unescape() diesen String wieder richtig auflösen.
Andersrum gehts eben mit escape() und dann urldecode().
Vielen dank für deinen Hinweis, mit der JS-Funktion unescape. Das hat soweit auch prima funktioniert, doch leider arbeitet diese Funktion nicht ganz genauso wie urldecode() auf PHP-Seite.
Leerzeichen (%20) werden zu "+"-Zeichen gewandelt. Man muss also noch mal Handanlegen und diese Zeichen zu ersetzen.
Ich habe dies so gelöst:
function unescape_complete(Ersetzen){
Ersetzen = Ersetzen.split('+').join('%20');
return unescape(Ersetzen);
}
Gute Info zu Httprequest, jedoch habe ich da noch ein Problem:
Wenn ich in der php-Datei eine SQL-Abfrage mache und dann das Javascript mit window.seTimeOut immerwieder durchlaufen lasse, werden leider keine Änderungen in der Datenbank angezeigt. Wenn ich sämtliche Browsercaches (Verlauf usw.) beim IE7 leere, dan geht es genau 1x. Gibt es da eine Lösung für?
Würd emich freuen.
Mfg
Jens
@Zensi
Du musst berücksichtigen, dass immer nur ein HttpRequest gleichzeitig über eine Funktion ausgeführt werden kann. Wenn du dann mit setTimeOut die Funktion wieder ausführst, wird der Request von davor überschrieben, usw.
Such mal in einem Framework nach einer Funktion, die erst wartet, bis ein Request fertig ist.
Toller Beitrag. Auch eine kleine Frage. Ich lese auf diesem Weg eine csv.Datei ein und verarbeite dann diese Daten. Was mir immer wieder passiert ist genau das Selbe, wie bei Zensi. Wenn ich etwas in der csv.datei ändere, aber den Browser nicht neu starte, oder das Cache lösche, gibt es keinen Update der Daten. An was könnte das liegen? Mfg. Thomas
bevor die CSV oder XML datei geladen wird sollte man mittels:
http.setRequestHeader("Pragma", "no-cache");
http.setRequestHeader("Cache-Control", "must-revalidate");
http.setRequestHeader("If-Modified-Since", "<datum>");
das Cachen der Datei verhindern.
Ich habe auch das Problem mit den nicht aktualisierten Daten bei erneutem Request gehabt. Meine Löstung war banal. Ich übergebe einfach an das PHP-Script eine zusätzliche Variable in Form der aktuellen Zeit, die im PHP-Script aber nicht gebraucht wird.
Das sieht dann wie folgt aus: '/phpsript.php?varxy=xy&update_string=' + new Date().getTime()
Durch den immer anderen Inhalt vom update_string kann der Browser nie die gecahten Inhalte benutzen und läd somit das PHP-Script immer neu.
Super! Genau was ich gesucht hatte. Eingefügt unf läuft, dies ist eher selten....
DANKE !!
Gruss aus Spanien - Jordi (Jürg)