AJAX / baseportal-Funktionen als Javascript ausführen | ab Version 3 |
baseportal bietet die auf den ersten Blick verblüffende Möglichkeit, beliebige baseportal-Funktionen (perl, php, loop etc.) erst im Browser bei der Anzeige der Seite auszuführen. Natürlich steckt dahinter ein kleiner Trick: In Wirklichkeit wird eine Verbindung zum Server hergestellt, der den Code ausführt und das Ergebnis zurückschickt. Auch Parameter können beim Aufruf übermittelt werden, die dann wie gewohnt bereitstehen.
Durch den Parameter script=... wird baseportal angewiesen, einen Befehl nicht wie sonst sofort, auf dem Server, auszuführen. Stattdessen wird eine Javascript-Funktion mit dem bei script angegebenen Namen bereitgestellt. Im Browser kann diese Funktion nun ganz normal wie in Javascript üblich aufgerufen werden. Sodann verbindet sich diese im Hintergrund mit der aufrufenden Seite, führt den Befehl aus und schickt das Ergebnis an eine Rückgabe-Funktion zurück. Der Name dieser Funktion kann über den Parameter return definiert werden. Gibt es diesen Parameter nicht, so heisst die Rückgabe-Funktion automatisch wie die über script definierte mit Unterstrich davor. Die Kommunikation mit dem Server läuft dabei "asynchron" ab, d.h. während auf das Ergebnis gewartet wird, bleibt der Browser nicht stehen, sondern es können weitere (Javascript-)Aktionen ausgeführt werden. An die Sende-Funktionen können optional bis zu 3 Parameter übergeben werden:
Name | Beschreibung |
---|---|
query | Parameter die per URL übergeben werden (CGI GET) |
post | Daten die über HTTP-Post gesendet werden (CGI POST) |
requestHeader | Parameter die im HTTP-Header gesetzt werden sollen |
In den allermeisten Fällen reicht die Übergabe über die URL, also die Angabe des 1. Parameters, aus. Nur bei sehr grossen Formular-Daten (z.B. Texteingabefelder) müssen diese wegen der Längenbeschränkung von URLs über post gesendet werden.
An die Rückgabe-Funktion werden 3 Parameter übergeben, die nach Bedarf ausgewertet werden können:
Name | Beschreibung |
---|---|
responseText | Die Rückgabe als einfacher Text |
responseXML | Die Rückgabe als XML-Daten (müssen entsprechend gesendet werden) |
status | Der Statuswert der Rückgabe. Enthält 200 wenn alles Ok ist, sonst den HTTP-Fehlercode |
Das folgende Beispiel übersetzt deutsche Begriffe ins Englische - sofort bei der Eingabe:
<loop script=getname range=0,10 db=/_bib/dict_de_en/dict_de_en> $Deutsch - $English<br> </loop> <script> function _getname(x) { document.getElementById("out").innerHTML=x; } </script> <p>Begriff: <input type=text onkeyup="getname('Deutsch~='+this.value)"><p/> <div id="out" width=500 height=200 style="border:1px solid red"></div>
Wie man sieht ist der Code denkbar einfach: Durch den Parameter script=... wird das <loop>..</loop> nicht auf dem Server ausgeführt. Stattdessen wird die Javascript-Funktion getname bereitgestellt, die bei jedem Tastendruck in einem Textfeld aufgerufen wird. Der Inhalt des Textfeldes wird als Parameter übergeben. Erst wenn der Nutzer einen Buchstaben eingibt wird das loop ausgeführt und fragt im Beispiel das Deutsch/Englisch-Wörterbuch ab. Nach Beendigung wird die Callback-Funktion _getname (da wir keinen anderen Namen mit return= angegeben haben) in Javascript aufgerufen und das Ergebnis als Parameter übergeben. Dieses wird einfach in einen div-Container geschrieben und somit angezeigt.
Hier ist das Beispiel in Aktion: http://baseportal.de/cgi-bin/baseportal.pl?htx=/baseportal/Projekte/ajax/loop
Ebenso kann Perl oder PHP als Javascript-Funktion definiert werden. Hier ein PHP-Aufruf:
<php script=phpversion> out("PHP-Version: ".phpversion()); </php> <script> function _phpversion(x) { alert(x) } </script> <input type=button value="PHP-Version" onclick="phpversion()">
Aufruf: http://baseportal.de/cgi-bin/baseportal.pl?htx=/baseportal/Projekte/ajax/php
Und hier ein kleines Perl-Skript das eine Bankverbindung auf Gültigkeit überprüft - sofort, während der Eingabe:
Aufruf: http://baseportal.de/cgi-bin/baseportal.pl?htx=/baseportal/Projekte/ajax/perl
Hier werden die neuesten 10 Einträge mit Namen und Titel als Liste ausgegeben und beim Darüberfahren mit der Maus, wird der jeweilige Eintrag im Detail gezeigt.
Aufruf: http://baseportal.de/cgi-bin/baseportal.pl?htx=/baseportal/Projekte/ajax/do_all
Um grosse Daten per POST zu übertragen, muss an das Skript einfach ein zweiter Parameter übergeben werden, z.B.:
Enthalten die zu übertragenden Daten Leer- oder Sonderzeichen, müssen diese mit encodeURIComponent für die Übertragung kodiert werden, z.B.:
Da AJAX-Daten immer mit UTF-8-Kodierung verschickt werden, müssen diese, wenn sie auf dem Server weiterverarbeitet werden, erst dekodiert werden. Das folgende Beispiel speichert den Inhalt eines Textfelds im Hintergrund per AJAX in einer Datenbank und liefert die Id des gespeicherten Datensatzes zurück:
<perl script=kontocheck>
$result=&KontoCheck($kto, $blz);
out "Konto: $kto<br>BLZ: $blz<br>Ergebnis: $result<br>Bank: $Name<br>PLZ: $PLZ<br>Ort: $Ort";
</perl>
<script>
function _kontocheck(r)
{
document.getElementById("out").innerHTML=r;
}
</script>
<p>
Konto-Nr.: <input type=text id='kto' onkeyup="kontocheck('kto='+this.value+'&'+'blz='+document.getElementById('blz').value)"><br/>
BLZ: <input type=text id='blz' onkeyup="kontocheck('kto='+document.getElementById('kto').value+'&'+'blz='+this.value)"><br/>
<p/>
<div id="out" width=500 height=200 style="border:1px solid red"></div>
Und natürlich kann auch die komplette Datenbank-Ausgabe als Javascript-Funktion verwendet werden:<do action=all db=/baseportal/forum script=database>
<script>
function _database(x)
{
document.getElementById("out").innerHTML=x;
}
</script>
<loop sort=- range=0,10 db=/baseportal/forum>
<div onmouseover='database("cmd=all&Id=$_id")'>$Name - $Titel</div>
</loop>
<div id="out" width=500 height=200 style="border:1px solid red"></div>
database("cmd=add", 'Titel:=Test&Text:='+text)
database("", 'Text='+encodeURIComponent(text))
<perl script=put_text>
put ["Text", convert_utf8($text)];
out "Daten unter der Id $_put_id gespeichert...";
</perl>
<script>
function _put_text(r)
{
document.getElementById("out").innerHTML=r;
}
</script>
<p>
<textarea type=text id='text' rows=10 cols=40>
</textarea><br/>
<input type=button value='Senden' onclick="put_text('','text='+encodeURIComponent(document.getElementById('text').value))"><br/>
<p/>
<div id="out"></div>