...
Webseitengestaltung
...
mit
...
CGI-Programmierung
...
1 Allgemeines
Bei der professionellen Gestaltung von Webseiten stößt man relativ schnell an die Grenzen der Möglichkeiten die reine HTML-Dokumente bieten. Einige Aufgaben machen es unerläßlich, daß der Webbesucher Programme auf dem Server ausführen darf. Dies stellt aber hohe Anforderung an die Sicherheit, weil es ausgeschlossen sein muß, auch andere Programme auszuführen, was schwerwiegende Probleme nach sich ziehen kann. Mit dem Common-Gateway-Interface (CGI) steht diese Möglichkeit zur Verfügung. Es ist integraler Bestandteil des Servers, welcher das ?http" - Protokoll bereitstellt.
2 Systemübersicht
Bild 1: Grundsätzlicher Aufbau des http-Servers mit CGI
Wird vom Client ein Dokument angefordert, trifft das CGI die Feststellung, ob der Dokumentpfad in das CGI-Programmverzeichnis oder in ein sonstiges Verzeichnis weist. Wird ein Programm im CGI-Programmverzeichnis angesprochen, wird dies vom CGI ausgeführt. Als Ergebnis liefert dieses Programm dann ein HTML-Dokument an das CGI. Dies geschieht über den Kanal ?Standardausgabe". Würde dieses Programm von der Shelloberfläche ?normal" ausgeführt erscheint dieses HTML-Dokument auf dem Bildschirm welcher üblicherweise das Standardausgabegerät darstellt.
Beispiel:
Code Block |
---|
#!/bin/sh#disable filename globbing set -f#Ich bin ein Dokument vom Typ text/html echo Content-type: text/html echo "" ##Die Die HTML-Tags werden mit dem Befehl echo ausgegeben. echo '<HTML>' echo '<HEAD>' echo '<TITLE> Ein Counter </TITLE>' echo '</HEAD>' echo '<BODY BGCOLOR="BBDDFF" TOPMARGIN=5 LEFTMARGIN=5 LINK=YELLOW VLINK=WHITE><CENTER>' echo '<H5>' echo 'Besucher seit dem 01.06.1999:' echo '</H5>' echo '<TABLE BORDER=0 CELLSPACING="0" CELLPADDING="0"><TR><TD>' ##Der Der Pfadname zur Counterdatei, die den letzten Wert enthält #enthält#Pfad Pfad vorhanden, Zugriffsrechte ?? COUNT_FILE=/tmp/cgi-count if [ ! -f $COUNT_FILE ] then # Wenn die Datei nicht existiert, dann mit dem Wert 0 anlegen. LAST_COUNT=0 echo $LAST_COUNT >$COUNT_FILE else # sonst Inhalt lesen und erhöhen, dann Speichern LAST_COUNT=`cat $COUNT_FILE` expr $LAST_COUNT + 1 >$COUNT_FILE fi #fi#Es Es ist ein 5-stelliger Zähler #Zähler#Der Der Wert wird jeweils durch die 5 Werte dividiert, das Ergebnis ergibt die #ergibt einzelnedie#einzelne Ziffer für jede Stelle for i in 10000 1000 100 10 1 do FILENAME=`expr $LAST_COUNT / $i` while [ $FILENAME -gt 9 ] do # solange der Wert größer 9 ist, weiter durch 10 teilen FILENAME=`expr $FILENAME % 10` done # Derdone#Der Wert bildet die Grundlage für den Dateinamen der Grafik, welche # diewelche#die einzelnen Ziffern enthält also 0.gif enthält die ?0" ##der der Tag für die Anzeige der Grafik echo '<img src=/graphics/'$FILENAME'.gif border="0">' done echo '</TD></TR></TABLE>' echo '</CENTER>' echo '</BODY></HTML>' *{+} |
Allgemeine
...
Hinweise:
...
Während
...
das
...
CGI-Script
...
läuft
...
stehen
...
gewisse
...
Umgebungsvariablen
...
zur
...
Verfügung,
...
wie
...
z.B.
...
der
...
Pfad,
...
das
...
aktuelle
...
Verzeichnis
...
usw.
...
Welche
...
Umgebungsvariablen
...
zur
...
Verfügung
...
stehen,
...
zeigt
...
das
...
bei
...
Apache
...
mitgelieferte
...
Script
...
?test-cgi"
...
das
...
folgenden
...
Inhalt
...
hat:
...
...
Code Block |
---|
#\!/bin/sh \# disable filename globbing set \-f echo Content-type: text/plain echo echo CGI/1.0 test script report: echo echo argc is $#. argv is "$*". echo echo SERVER_SOFTWARE = $SERVER_SOFTWARE echo SERVER_NAME = $SERVER_NAME echo GATEWAY_INTERFACE = $GATEWAY_INTERFACE echo SERVER_PROTOCOL = $SERVER_PROTOCOL echo SERVER_PORT = $SERVER_PORT echo REQUEST_METHOD = $REQUEST_METHOD echo HTTP_ACCEPT = "$HTTP_ACCEPT" echo PATH_INFO = "$PATH_INFO" echo PATH_TRANSLATED = "$PATH_TRANSLATED" echo SCRIPT_NAME = "$SCRIPT_NAME" echo QUERY_STRING = "$QUERY_STRING" echo REMOTE_HOST = $REMOTE_HOST echo REMOTE_ADDR = $REMOTE_ADDR echo REMOTE_USER = $REMOTE_USER echo AUTH_TYPE = $AUTH_TYPE echo CONTENT_TYPE = $CONTENT_TYPE echo CONTENT_LENGTH = $CONTENT_LENGTH |
Bild
...
8:
...
Die
...
Datei
...
test-cgi
...
mit
...
den
...
verwertbaren
...
Umgebungsvariablen
...
...
Die
...
Variable
...
$QUERY_STRING
...
dient
...
der
...
Kommunikation
...
zwischen
...
dem
...
aufrufenden
...
HTML-Dokument
...
und
...
dem
...
CGI-Script,
...
wenn
...
z.B.
...
vom
...
Benutzer
...
eingegebene
...
Daten
...
weitergeleitet
...
werden
...
müssen.
...
Hierbei
...
wird
...
im
...
HTML-Dokument
...
eine
...
FORM
...
deklariert,
...
und
...
als
...
Kommunikationsform
...
mit
...
dem
...
?ACTION"-Script
...
die
...
Methode
...
?GET"
...
gewählt.
...
Das
...
verwendete
...
Beispiel
...
eines
...
Gästebuchs
...
zeigt
...
diese
...
Datenübergabe
...
über
...
die
...
Methode
...
?GET".
...
Hierbei
...
werden
...
über
...
die
...
Umgebungsvariable
...
QUERY_STRING
...
Daten
...
vom
...
CGI-Script
...
ausgewertet.
...
Die
...
ebenso
...
mögliche
...
Methode
...
POST
...
übergibt
...
die
...
Daten
...
an
...
das
...
CGI-Script
...
über
...
den
...
Standardeingabekanal.
...
Das
...
Beispiel
...
besteht
...
aus
...
mehreren
...
HTML
...
-
...
und
...
CGI-Scripten:
...
Dateiname | Verwendung |
/gaestebuch/gb-neu.htm |
...
Maske |
...
zur |
...
Erfassung |
...
eines |
...
neuen |
...
Gästbucheintrags |
...
/cgi-bin/gb-neu.sh |
...
Ausführungsscript |
...
für |
...
einen |
...
neuen |
...
Gästebucheintrag |
...
/cgi-bin/gb-query.sh |
...
Anzeige |
...
der |
...
Einträge |
...
des |
...
Gästebuchs | <HTML><TITLE>Eintrag in das Gästebuch </TITLE> |
Code Block |
---|
<BODY BGCOLOR="#BBDDFF">\\ Wenn Sie einen neuen Eintrag vornehmen möchtenmöchten,<BR>\\ geben Sie bitte Ihre persönlichenpersönlichen Daten<BR>\\ und einen Kommentar an:<BR>\\ <FORM ACTION="/cgi-keipke/gb-neu.sh" METHOD="GET">\\ <TABLE BORDER="1"><TR><TD>\\ Name:\\ </TD><TD>\\ <INPUT TYPE="text" SIZE="20" MAXLENGTH="20" NAME="BESUCHER">\\ </TD></TR><TR><TD>\\ Vorname:\\ </TD><TD>\\ <INPUT TYPE="text" SIZE="20" MAXLENGTH="20" NAME="VORNAME">\\ </TD></TR><TR><TD>\\ EMail:\\ </TD><TD>\\ <INPUT TYPE="text" SIZE="60" MAXLENGTH="60" NAME="EMAIL">\\ </TD></TR><TR><TD>\\ Kommentar:\\ </TD><TD>\\ <INPUT TYPE="text" SIZE="60" MAXLENGTH="60" NAME="KOMMENTAR">\\ </TD></TR>\\ </TABLE>\\ <INPUT TYPE="submit" VALUE="Eingabe OK">\\ <INPUT TYPE="reset" VALUE="Eingabe löschenlöschen">\\ </FORM>\\ </BODY>\\ </HTML> |
Bild
...
9:
...
Die
...
Datei
...
/gaestebuch/gb-neu.htm
...
Code Block |
---|
#\!/bin/sh \# disable filename globbing set \-f echo Content-type: text/html echo "" echo '<HTML><HEAD>' echo '<BODY BGCOLOR="#BBDDFF">' \# Der Pfad für die Datei, welche die Gästebuchdaten enthält GB_DIR=/www/htdocs/keipke/gaestebuch.data \# Der Dateiname GB_FILE=$GB_DIR/gaestebuch.data \ # Herausfiltern der eingegebenen Daten aus dem String ?$QUERY_STRING" NAME=`echo $QUERY_STRING\|cut \-d'&' \-f1\|cut \-c 10-` VORNAME=`echo $QUERY_STRING\|cut \-d'&' \-f2\|cut \-c 9-` EMAIL=`echo $QUERY_STRING\|cut \-d'&' \-f3\|cut \-c 7-` KOMMENTAR=`echo $QUERY_STRING\|cut \-d'&' \-f4\|cut \-c 11-` DATE_TIME=`date \+'%d.%m.%y %T'` NAME=`/www/htdocs/keipke/cgi-bin/charchg.sh $NAME` VORNAME=`/www/htdocs/keipke/cgi-bin/charchg.sh $VORNAME` EMAIL=`/www/htdocs/keipke/cgi-bin/charchg.sh $EMAIL` KOMMENTAR=`/www/htdocs/keipke/cgi-bin/charchg.sh $KOMMENTAR` \# Ausgabe der Daten zur Bestätigung oder Fehler echo 'Ihre Eingabe:<BR><BR>' echo '<TABLE BORDER="1"><TR>' echo '<TD>' echo Zeit echo '</TD>' echo '<TD>' echo $DATE_TIME echo '</TD></TR><TR>' echo '<TD>' echo Name echo '</TD>' echo '<TD>' echo $NAME echo '<TD></TR><TR>' echo '</TD>' echo '<TD>' echo Vorname echo '</TD>' echo '<TD>' echo $VORNAME echo '</TD></TR><TR>' echo '<TD>' echo EMail echo '</TD>' echo '<TD>' echo $EMAIL echo '</TD></TR><TR>' echo '<TD>' echo Kommentar echo '</TD>' echo '<TD>' echo $KOMMENTAR echo '</TD>' echo '</TR></TABLE><BR>' if \[ \-z $NAME \] \|\| \[ \-z $EMAIL \] \|\| \[ \-z $KOMMENTAR \] then echo 'konnte nicht gespeichert werden, weil<BR>' echo 'die Felder Name, EMail oder Kommentar<BR>' echo 'nicht ausgefülltausgefüllt wurden.<BR>' echo 'Gehen Sie überüber Ihren Browser mit dem<BR>' echo 'Schalter "Back" oder "ZurückZurück" zur vorherigen<BR>' echo 'Eingabemaske zurück<BR>zurück<BR>' else if \[ \-d $GB_DIR \] then \# Wenn das Verzeichnis existiert if \[ \-w $GB_DIR \] then \# Wenn das Verzeichnis beschreibbar ist if \[ \! \-f $GB_FILE \] then \# Wenn die Datei noch nicht existiert, dann anlegen touch $GB_FILE else if \[ \-w $GB_FILE \] then \# Wenn die Datei beschreibbar ist echo $DATE_TIME'\|'$NAME'\|'$VORNAME'\|'$EMAIL'\|'$KOMMENTAR >>$GB_FILE echo 'wurde erfolgreich in das GästebuchGästebuch eingetragen' echo 'Vielen Dank fürfür Ihren Besuch<BR><BR>' echo '<a href="../main.htm">Zurück >Zurück zur Leitseite</a>' else echo 'konnte nicht gespeichert werden.<BR>' echo 'Die Datendatei ist nicht beschreibbar.' fi fi else echo 'konnte nicht gespeichert werden.<BR>' echo 'Das Verzeichnis ist nicht beschreibbar.' fi else echo 'konnte nicht gespeichert werden.<BR>' echo 'Das Verzeichnis existiert nicht.' fi fi echo '</BODY></HTML>' |
Bild
...
10:
...
Die
...
Datei
...
/cgi-bin/gb-neu.sh
...
Code Block |
---|
#\!/bin/sh \# aus dem als Parameter übergebenen Wert werden bestimmte Sonderzeichen ausgetauscht. Weil z.B. vom Brwoser %40 für einen @ geliefert wird. if \[ $# \-eq 0 \] then exit fi for i in $\* do echo $i\|sed \-e 's/%40/@/g' \-e 's/%E4/ä/g' \-e 's/%F6/ö/g' \-e 's/%FC/ü/g' \-e 's/%C4/Ä/g' \-e 's/%D6/Ö/g' \-e 's/%DC/Ü/g' \-e 's/%DF/ß/g' \-e 's/%2C/,/g' \-e 's/+/ /g' \-e 's/%28/8/g' \-e 's/%29/)/g' \-e 's/%3C/</g' \-e 's/%3D/>/g' \-e 's/%22/\"/g' \-e 's/%21/\!/g' done |
Bild
...
11:
...
Die
...
Datei
...
/cgi-bin/charchg.
...
sh
Code Block |
---|
#!/bin/sh \# disable filename globbing set \-f echo echo Content-type: text/html echo "" echo '<HTML><BODY BGCOLOR="#BBDDFF">' GB_DIR=/www/htdocs/keipke/gaestebuch.data GB_FILE=$GB_DIR/gaestebuch.data if \[ \-s $GB_FILE \] then \# Wenn die datei existiert und nicht leer ist echo '<H1>Gästebuch<H1>Gästebuch von www.keipke.de</H1><BR>' echo 'Es werden die (max.) letzten 20 EinträgeEinträge aus<BR>' echo 'dem GästebuchGästebuch angezeigt.<BR>' echo 'Insgesamt sind zur Zeit' \# Ermittlung Anzahl Zeilen cat $GB_FILE\|wc \-l echo 'EinträgeEinträge vorhanden<BR><BR>' echo '<TABLE BORDER="1">' \# Die letzten 20 Zeilen oder weniger holen. Die Formatierung als Tabelle \# übernimmt der awk. Hierbei werden die pipezeichen durch TR/TD-tags ersetzt. tail \-20 $GB_FILE\|awk \-F'\|' ' $1 \!= "" { print "<TR><TD>"$1"</TD><TD>"$2"</TD><TD>"$3"</TD><TD>"$4"</TD><TD>"$5"</TD></TR>" } ' echo '</TABLE>' else echo 'Das Gästebuch enthältGästebuch enthält zur Zeit' echo 'noch keine EinträgeEinträge. Versuchen Sie' echo 'es zu einem späterenspäteren Zeitpunkt noch einmal.' fi echo '</BODY></HTML>' |
Bild
...
12:
...
Die
...
Datei
...
gb-query.sh
...