vorheriges KapitelInhaltsverzeichnisIndexInfoseitenächstes Kapitel


Was ist ein CGI-Skript?

CGI-Skripten benutzen?

Die Anatomie eines CGI-Skripts

Problemlösungen

CGI-Variablen

Programme zum Dekodieren

Non-processed Header-Skripts - (NPH-Skripts)

Zusammenfassung

Fragen und Antworten


Tag 10

Kapitel 19 - CGI-Programmierung

CGI steht für Common Gateway Interface, eine Methode, Programme auf einem Web-Server entsprechend den Eingaben eines Web-Browsers auszuführen. Gateway-Skripten erlauben Ihren Lesern, Ihre Webseiten zu beeinflussen - um in einer Datenbank nach einem Eintrag zu suchen, um das, was Sie geschrieben haben, zu kommentieren oder um einzelne Punkte in einem Formular auszuwählen und dann eine entsprechend zusammengestellte Antwort zu erhalten. Wenn Ihnen im Web schon jemals ein auszufüllendes Formular oder eine Suchabfrage untergekommen ist, dann haben Sie ein CGI-Skript benutzt. Vielleicht ist Ihnen das nicht einmal aufgefallen, weil die meiste Arbeit auf dem Web-Server hinter den Kulissen erledigt wird. Sie sehen nur das Ergebnis.

Als Web-Autor erzeugen Sie alle Seiten des Gateways: die Seite, welche die Leser sehen, die Programmierung auf der Server-Seite, um die Lesereingaben zu verarbeiten, und das Resultat, das an die Leser zurückgemeldet wird. CGI-Skripten sind ein extrem wirkungsvolles Feature der Interaktion zwischen Web-Browsern und Servern, die Ihre Meinung, eine Web-Präsentation betreffend, komplett ändern können.

Dieses Kapitel erklärt eine Menge über CGI-Skripte, unter anderem

Die nächsten beiden Kapitel behandeln vorwiegend Web-Server, die auf Unix-Systemen laufen, so daß die meisten Beispiele und Anweisungen nur unter Unix angewandt werden können. Wenn Sie einen Web-Server oder ein System betreiben, das nicht auf Unix beruht, werden Sie die Methoden zur Erzeugung von CGI-Skripten, die in diesem Abschnitt vorgestellt werden, nicht unbedingt anwenden können. Sie werden hier aber trotzdem herausfinden, wie CGI ungefähr funktioniert, und können Ihr Wissen dann mit der Dokumentation von CGI auf Ihrem speziellen Server anwenden und erweitern.

 

Was ist ein CGI-Skript?

Ein CGI-Skript ist, einfach ausgedrückt, ein Programm, das auf dem Web-Server abläuft, ausgelöst durch Eingaben, die in einem Browser gemacht werden. Das Gateway-Skript stellt üblicherweise eine Verbindung dar zwischen dem Server und einem anderen Programm, das auf dem System läuft, beispielsweise einer Datenbank.

Gateway-Skripten müssen nicht unbedingt Skripten sein - je nachdem, was Ihr Server unterstützt, können es kompilierte Programme sein, Batch-Dateien oder etwas anderes Ausführbares. Um der einfachen Ausdrucksweise willen nenne ich sie in diesem Kapitel jedoch einfach Skripte.

Ein CGI-Skript ist ein jegliches Programm, das auf einem Web-Server läuft. CGI steht für »Common Gateway Interface« (allgemeine Übergabeschnittstelle) und besteht aus grundlegenden Variablen und Mechanismen, um Informationen vom Browser zum Server weiterzuleiten.

CGI-Skripten können auf zwei Arten verwendet werden: als die ACTION eines Formulars oder als direktes Link auf eine Seite. Skripten zur Formularverarbeitung unterscheiden sich geringfügig von normalen CGI-Skripten, jedoch haben beide eine sehr ähnliche Erscheinung und ein ähnliches Verhalten. Im ersten Teil dieses Kapitels werden Sie etwas über allgemeine (generic) CGI-Skripten lernen und sich dann zu Skripten weiterbewegen, die Formulare verarbeiten.

 

Wie funktionieren CGI-Skripte?

Gateway-Skripten werden vom Server aufgerufen, basierend auf den Angaben des Browsers. Abbildung 19.1 zeigt den Weg zwischen Browser, Server und dem Skript.

siehe Abbildung

Abbildung 19.1:
Browser an Server an Skript an Programm und wieder zurück

Hier eine kurze Beschreibung dessen, was tatsächlich vor sich geht:

1. Eine URL verweist auf ein CGI-Skript. Die URL eines CGI-Skripts kann überall da auftreten, wo eine normale URL sein könnte, z.B. in einem Link oder in einem Bild. Meistens tritt eine URL jedoch als ACTION eines Formulars auf. Der Browser kontaktiert den Server dann mit dieser URL.

2. Der Server empfängt die Anforderung, erkennt, daß die URL auf ein Skript verweist (je nach Server abhängig vom Ablageort des Skripts oder seiner Endung) und führt das Skript aus.

3. Gesteuert von den Eingaben des Browsers, soweit es diese gibt, führt das Skript eine Aktion durch. Diese Aktion kann aus dem Durchsuchen einer Datenbank bestehen, dem Berechnen eines Werts oder einfach dem Aufruf eines anderen Programms auf dem System.

4. Das Skript formatiert seine Ergebnisse in einer Weise, die der Web-Server verstehen kann.

5. Der Web-Server erhält das Ergebnis vom Skript und reicht es zum Browser weiter, der es für die Leser formatiert und anzeigt.

Verstanden? Nein? Macht nix, es kann ein verwirrender Ablauf sein. Lesen Sie weiter, es wird mit den nächsten paar Beispielen klarer werden.



Ein einfaches Beispiel

Hier haben wir ein einfaches Beispiel mit einer Schritt-für-Schritt-Erklärung dessen, was auf allen Seiten des Prozesses passiert. In Ihrem Browser stoßen Sie auf eine Seite wie jene, die in Abbildung 19.2 dargestellt ist.


siehe Abbildung

Abbildung 19.2:
Eine Seite mit einer Skript-Verbindung

Die Verbindung zu »Display the Date« ist eine Verknüpfung mit einem CGI-Skript, eingebettet in den HTML-Code der Seite, wie es bei jeder anderen Verbindung auch der Fall wäre. Könnten Sie den HTML-Code der Seite sehen, würde er ungefähr so aussehen:

<A HREF="http://www.somesite.com/cgi-bin/getdate">Display the Date</A>

Der Umstand, daß da cgi-bin im Pfad-Namen auftaucht, ist ein starkes Indiz dafür, daß es sich um ein Gateway-Skript handelt, weil dies bei vielen Servern der einzige Ort ist, an dem CGI-Skripten abgelegt werden können.

Wenn Sie die Verbindung anwählen, fordert der Browser die URL vom Server des Systems www.somesite.com an. Der Server nimmt die Anfrage entgegen und erkennt anhand seiner Konfiguration, daß die übermittelte URL ein Skript namens getdate.cgi ist, und führt das Skript aus.

Das Skript, in diesem Falle ein unter Unix ausführbares Shell-Skript, sieht etwa so aus:

#!/bin/sh

echo Content-type: text/plain
echo

/bin/date


Dieses Skript erledigt zwei Dinge: Es gibt die Zeile Content-type: text/plain und danach eine Leerzeile aus, und es ruft das Unix-date-Programm auf, welches das Datum und die Uhrzeit ausgibt. Daher würde die komplette Ausgabe des Skripts etwa so aussehen:

 

Content-type: text/plain
Tue Oct 25 16:15:57 EDT 1994

 

Was hat es mit dem Content-type (Inhaltstyp) auf sich? Das ist eine Art Spezialcode, den der Server an den Browser weiterreicht, um ihm mitzuteilen, um welche Art von Dokument es sich handelt. Der Browser verwendet diesen Code dann, um herauszufinden, ob er das Dokument anzeigen kann oder nicht oder ob er dafür ein externes Programm (Viewer) starten muß. Die Besonderheiten dieser Zeile lernen Sie später in diesem Kapitel kennen.

Nachdem die Ausführung des Skripts beendet ist, erhält der Server das Ergebnis und gibt es an den Browser weiter. Der Browser hat die ganze Zeit geduldig auf irgendeine Reaktion gewartet. Und wenn der Browser sie erhält, zeigt er einfach Datum und Uhrzeit an (Abbildung 19.3).

siehe Abbildung

Abbildung 19.3:
Das Ergebnis des Datum-Skripts

Das ist also die Grundidee. Obgleich die Dinge auch sehr viel komplizierter werden können, ist es doch diese Wechselwirkung zwischen Browser, Server und Skript, die den Kern dessen ausmacht, wie ein CGI-Skript funktioniert.


CGI-Skripten benutzen?

Bevor Sie CGI-Skripten in Ihren Web-Präsentationen anwenden können, müssen mehrere grundlegende Bedingungen von Ihnen und Ihrem Server erfüllt werden. CGI-Skripting ist ein erweitertes Web-Feature und erfordert Wissen auf Ihrer Seite und Kooperation auf seiten des Web-Server-Anbieters. Vergewissern Sie sich, daß Sie alle Fragen in diesem Abschnitt beantworten können, bevor Sie weitermachen.

 

Ist Ihr Server dazu konfiguriert, CGI-Skripten zuzulassen?

Um CGI-Skripten zu schreiben und auszuführen, brauchen Sie einen Web-Server. Im Unterschied zu regulären HTML-Dateien können Sie CGI-Skripten nicht auf Ihrem lokalen System schreiben und testen; Sie müssen dies durch einen Web-Server erledigen.

Aber sogar wenn Sie einen Web-Server haben, muß dieser auf spezielle Weise konfiguriert sein, um CGI-Skripten verarbeiten zu können. Das bedeutet normalerweise, daß alle Ihre Skripten in einem speziellen Verzeichnis namens cgi-bin aufgehoben werden.

Bevor Sie CGI-Skripten ausprobieren, sollten Sie Ihren Server-Administrator fragen, ob Sie CGI-Skripten installieren und ausführen dürfen, und wenn ja, wo Sie sie speichern können. Außerdem muß es sich bei dem Server um einen echten Web-Server handeln - wenn Sie Ihre Webseiten auf einem FTP- oder Gopher-Server publizieren, können Sie CGI nicht anwenden.

Wenn Sie Ihren eigenen Server verwalten, müssen Sie ein spezielles cgi-bin-Verzeichnis erzeugen und Ihren Server so konfigurieren, daß er dieses Verzeichnis als Skript-Verzeichnis erkennt (was ein Teil der Serverkonfiguration ist, die sich natürlich von Server zu Server unterscheidet). Doch bedenken Sie die folgenden Punkte, die von CGI-Skripten aufgeworfen werden:


Können Sie programmieren?

Achtung, Anfänger! Damit Sie mit Hilfe von CGI Formulare verarbeiten oder irgendeine interaktive Aktion im World Wide Web vornehmen können, sollten Sie ein grundlegendes Verständnis für Programmierkonzepte und Methoden mitbringen. Außerdem sollten Sie mit Ihrem System gut vertraut sein. Wenn Sie diesen Hintergrund nicht mitbringen, sollten Sie entweder jemand anderen um Hilfe bitten, ein Buch über Programmiergrundlagen lesen oder einen Programmierkurs belegen. Dieses Buch kann nicht gleichzeitig Programmiergrundlagen und CGI-Programmierung beschreiben. Für dieses Kapitel setze ich voraus, daß Sie den Beispielcode lesen können und ihn auch verstehen.


Welche Programmiersprache sollten Sie verwenden?

Sie können so gut wie jede Programmiersprache anwenden, mit der Sie vertraut sind, um CGI-Skripten zu schreiben, solange Sie dabei die Regeln aus dem nächsten Abschnitt befolgen und solange diese Sprache mit dem Betriebssystem Ihres Web-Servers kompatibel ist. Manche Server unterstützen nur Programme, die in einer bestimmten Sprache geschrieben sind. Beispielsweise benutzen MacHTTP und WebStar AppleSkript für Ihre CGI-Skripte; WinHTTPD und WebSite verwenden Visual Basic. Um CGI-Skripten für Ihren Server zu schreiben, müssen Sie in einer Programmiersprache schreiben, die von Ihrem Server akzeptiert wird.

In diesem Kapitel und auch im weiteren Verlauf des Buches werde ich diese CGI-Skripten in zwei Sprachen schreiben: in der Unix Bourne Shell und in Perl. Die Bourne Shell gibt es fast auf jedem Unix-System. Sie ist zwar verhältnismäßig einfach zu lernen, jedoch kann es schwierig sein, etwas Kompliziertes mit ihr anzufangen. Perl andererseits ist kostenlos erhältlich, Sie müssen es jedoch herunterladen und auf Ihrem System kompilieren. Die Sprache selbst ist sehr flexibel und leistungsfähig (vergleichbar einer Programmiersprache wie C), ist aber auch sehr schwierig zu erlernen.


Ist Ihr Server richtig konfiguriert?

Um CGI-Skripten auszuführen, seien diese nun sehr einfache Skripten oder Skripte, die Formulare verarbeiten, muß Ihr Server ausdrücklich dazu konfiguriert sein. Dies kann bedeuten, daß Ihre Skripten in einem speziellen Verzeichnis aufbewahrt werden oder eine besondere Dateierweiterung haben müssen, je nachdem, welchen Server Sie verwenden und wie er konfiguriert ist.

Wenn Sie Platz auf einem Web-Server mieten oder wenn jemand anderer dafür zuständig ist, Ihren Web-Server zu administrieren, sollten Sie die zuständige Person fragen, ob CGI-Skripten zulässig sind, und wenn ja, wo sie hingehören.

Wenn Sie Ihren eigenen Server verwalten, prüfen Sie die Dokumentation für diesen Server, um zu sehen, wie er mit CGI-Skripten umgeht.


Was, wenn Sie kein Unix verwenden?

Wenn Sie nicht mit Unix arbeiten, geben Sie nicht gleich auf. Sie werden hier noch genügend allgemeine Informationen finden, die auf Ihren Server anwendbar sein könnten. Und um Ihnen noch ein wenig allgemeinen Hintergrund zu geben, kommen hier noch ein paar Informationen über CGI auf gewöhnlichen Web-Servern.

WinHTTPD für Windows 3.x und WebSite für Windows 95 und NT enthalten beide CGI-Fähigkeiten, mit denen Sie Formular- und CGI-Eingaben verarbeiten können. Beide Server beinhalten auch einen CGI-Modus für DOS und Windows. Letzterer erlaubt es Ihnen, CGI mit Visual Basic zu schreiben. Der DOS-Modus kann dazu konfiguriert werden, mit CGI-Skripten von Perl oder Tcl (oder jeder anderen Sprache) fertigzuwerden. WebSite hat auch einen CGI-Modus, mit dem Sie Perl und Windows-Shell-Skripten anwenden können.

Ganz ähnlich verhält es sich mit Netscape's Web-Server-Linie, FastTrack und Enterprise Web-Server eingeschlossen. Diese unterstützen die gesamte Bandbreite der CGI-Möglichkeiten. Der Enterprise Server z.B. unterstützt den Shell CGI-, den normalen CGI- und den Windows CGI-Modus. Dies gibt Ihnen die Flexibilitä,t den besten Ansatz für Ihre Bedürfnisse zu wählen. Auch die aktuelle Version des Internet Information Server von Microsoft (Version 3.0) unterstützt CGI in verschiedenen Formen.

MacHTTP bekommt seine CGI-Fähigkeiten von AppleSkript-Skripten. (MacHTTP ist die ursprüngliche Shareware Version des kommerziellen Web-Servers WebStar, der bei StarNine erhältlich ist.) John Wiederspan hat ein ausgezeichnetes Tutorial über die Anwendung von AppleSkript-CGI geschrieben, welches in der MacHTTP-Dokumentation enthalten ist.

Die Anatomie eines CGI-Skripts

Wenn Sie es so weit geschafft und die Warnungen und Konfiguration hinter sich haben, Glückwunsch! Jetzt können Sie CGI-Skripten und Formulare für Ihre Präsentationen schreiben. In diesem Abschnitt werden Sie erfahren, wie Ihre Skripten sich verhalten sollten, so daß der Server sich mit ihnen unterhalten und die korrekte Antwort zurückerhalten kann.


Ausgabe-Header

Ihre CGI-Skripten werden normalerweise irgendeine Art von Eingabe vom Browser über den Server bekommen. Sie können mit den erhaltenen Informationen im Inhaltsteil Ihres Skripts anfangen, was Sie wollen, solange die Ausgabe des Skripts einer speziellen Form folgt.

Wenn ich »Ausgabe des Skripts« sage, meine ich damit die Daten, die Ihr Skript zurück zum Server schickt. Bei Unix wird die Ausgabe zur Standardausgabe geschickt, wo der Server sie sich abholt. Bei anderen Systemen und anderen Servern kann Ihre Skript-Ausgabe woanders hingehen, Sie können sie z.B. in eine Datei auf der Platte schreiben oder die Ausgabe auch ausdrücklich zu einem anderen Programm hinsenden. Auch hier sollten Sie wieder die Dokumentation Ihres Servers aufmerksam durchlesen, um herauszufinden, wie CGI-Skripten auf diesem Server ausgeführt werden.

Als erstes sollte Ihr Skript einen speziellen Header ausgeben, der dem Server und schließlich dem Browser Informationen über die restlichen Daten gibt, die Ihr Skript erzeugen wird. Der Header ist nicht wirklich Teil des Dokuments; er wird nie irgendwo angezeigt. Tatsächlich senden Web-Server und -Browser die ganze Zeit über derartige Angaben hin und her; Sie sehen sie jedoch nie.

Es gibt drei Arten möglicher Einträge im Header, die Sie mit Skripten erzeugen können: Content-type, Location und Status. Content-type ist der meistverbreitete, daher erkläre ich ihn hier; über Location und Status erfahren Sie später in diesem Kapitel etwas.

Sie haben den Content-type-Header bereits vorher in diesem Buch kennengelernt; Inhalts-Typen werden von den Browsern verwendet, um herauszufinden, was für einen Datentyp sie empfangen. Da Skript-Ausgabe keine Dateierweiterung hat, müssen Sie dem Browser ausdrücklich mitteilen, was für eine Art von Daten Sie zurücksenden. Dazu setzen Sie den Content-type-Header ein.

Ein Content-type-Header besteht aus den Wörtern »Content-type«, einem speziellen Code zur Beschreibung der Dateiart und einer Leerzeile, wie hier:

Content-type: text/html

In diesem Beispiel sind die auf den Header folgenden Daten vom Typ text/html; mit anderen Worten, es ist eine HTML-Datei. Jedes Datei-Format, mit dem Sie arbeiten, wenn Sie Web-Präsentationen erzeugen, besitzt einen entsprechenden Inhaltstyp, daher sollte das Format der Ausgabe Ihres Skripts damit zusammenpassen. Tabelle 19.1 zeigt die gebräuchlichen Formate und die entsprechenden Inhaltstypen.

Tabelle 19.1: Dateiformate und Inhaltstypen

Format

Content-Type

HTML

text/html

Text

text/plain

GIF

image/gif

JPEG

image/jpeg

PostSkript

application/postskript

MPEG

video/mpeg

Beachten Sie, daß die Content-type-Zeile von einer Leerzeile gefolgt werden muß. Der Server kann nicht erkennen, wo der Header aufhört, und die Daten beginnen, wenn Sie diese Leerzeile nicht einfügen.



Ausgabedaten

Der Rest, den Ihr Skript erzeugt, sind die wirklichen Daten, die Sie zum Browser schicken wollen. Der Inhalt, den Sie in diesem Teil ausgeben, sollte zu dem Inhaltstyp passen, den Sie (im Header) dem Server mitgeteilt haben, d.h. wenn Sie den Inhaltstyp text/html benutzen, dann sollte der Rest der Ausgabe eine HTML-Datei sein. Wenn Sie einen Inhaltstyp image/gif verwenden, sollte die restliche Ausgabe eine binäre GIF-Datei sein usw., mit allen anderen Inhaltstypen.

Übung 19.1: Probieren Sie's

Diese Übung ähnelt dem einfachen Beispiel weiter vorne in diesem Kapitel - jenem, welches das Datum ausgab. Das CGI-Skript prüft, ob ich in meinen Web-Server eingeloggt bin, und sendet dann einen Bericht darüber zurück, was es gefunden hat (wie es in Abbildung 19.4 gezeigt wird).

siehe Abbildung

Abbildung 19.4:
Das Skript pinglaura meldet zurück, ob ich angemeldet bin

Dies ist die einfachste Form eines CGI-Skripts, das von einer Webseite durch ein einfaches Link aufgerufen werden kann, so wie hier:

<A HREF="http://www.lne.com/cgi-bin/pinglaura">Is Laura Logged in?</A>

Wenn Sie ein CGI-Skript so verknüpfen, wird das Skript ausgeführt, wenn Sie das Link auswählen. Es erfolgt keine Eingabe in das Skript; es läuft einfach ab und sendet Daten zurück.

Zunächst legen wir den Inhaltstyp der Ausgabe fest. Da dies ein HTML-Dokument sein wird, ist der Inhaltstyp text/html. Damit erstellt der erste Teil Ihres Skripts also eine Zeile mit dem Inhaltstyp und danach eine Leerzeile (vergessen Sie bloß die Leerzeile nicht!):

#!/bin/sh
echo "Content-type: text/html"
echo


Nun ergänzen wir den Rest des Skripts: den Inhalt des HTML-Dokuments, den Sie selbst innerhalb des Skripts zusammenbauen müssen. Im wesentlichen ist es das Folgende, was Sie zu tun haben:


Beginnen wir mit dem ersten HTML-Teil. Die folgenden Befehle erledigen dies in der Unix-Shell:

echo "<HTML><HEAD>"
echo "<TITLE>Is Laura There?</TITLE>"
echo "</HEAD><BODY>"

Testen Sie jetzt, ob ich im System angemeldet bin, indem Sie den who-Befehl eingeben (meine ID ist lemay), und speichern Sie das Ergebnis als die Variable ison. Wenn ich eingeloggt bin, wird die ison-Variable einen Inhalt haben, andernfalls wird sie leer sein.

ison='who | grep lemay'

Testen Sie das Ergebnis, und schicken Sie dann die entsprechende Nachricht als Teil der Skript-Ausgabe:

if [ ! -z "$ison" ]; then
echo "<P>Laura is logged in."
else
echo "<P>Laura isn't logged in."
fi

Dann schließen Sie die restlichen HTML-Tags ab:

echo "</BODY></HTML>"

Sie sind fertig! Wenn Sie jetzt das Programm für sich alleine von einer Kommandozeile aus testen würden, um die Ausgabe herauszufinden, bekämen Sie als Ergebnis, daß ich nicht in Ihr System eingeloggt bin, was ungefähr so aussähe (es sei denn, natürlich, daß ich online bin):

Content-type: text/html

<HTML><HEAD>
<TITLE>Are You There?</TITLE>
</HEAD><BODY>
<P>Laura is not logged in.
</BODY></HTML>

Sieht aus wie ein normales HTML-Dokument, nicht wahr? Das soll es auch. Die Ausgabe von Ihrem Skript wird zum Server und von da zum Browser geschickt, so daß es in einem Format sein sollte, das der Browser verstehen kann - in diesem Fall eine HTML-Datei.

Nun installieren Sie das Skript an der richtigen Stelle auf Ihrem Server. Dieser Schritt unterscheidet sich je nach der Plattform, auf der Sie arbeiten, und dem Server, den Sie benutzen. Meistens befindet sich auf Unix-Servern ein spezielles cgi-bin-Verzeichnis für Skripte. Kopieren Sie das Skript dorthin, und machen Sie es ausführbar.

Wenn Sie keinen Zugang zum cgi-bin-Verzeichnis haben, sollten Sie Ihren Web-Server-Administrator darum bitten. Sie können nicht einfach ein cgi-bin-Verzeichnis erstellen und dann Ihr Skript dort hineinkopieren; das funktioniert nicht. Kontaktieren Sie Ihren Web-Master.

Nachdem Sie nun ein lauffähiges Skript haben, können Sie es von einer Webseite aus aufrufen, indem Sie ein Link dorthin erzeugen, wie ich bereits erwähnt habe. Nur zum Vergleich hier nochmals das fertige Skript:

#!/bin/sh

echo "Content-type: text/html"
echo
echo "<HTML><HEAD>"
echo "<TITLE>Is Laura There?</TITLE>"
echo "</HEAD><BODY>"

ison=[ag]who | grep lemay[ag]

if [ ! -z "$ison" ]; then
echo "<P>Laura is logged in"
else
echo "<P>Laura isn't logged in"
fi

echo "</BODY></HTML>"

Skripten mit Parametern

CGI-Skripten sind am nützlichsten, wenn sie so allgemein wie möglich geschrieben werden. Wenn Sie beispielsweise herausfinden wollten, ob verschiedene Leute im System eingeklinkt sind, und dabei das Skript aus dem vorigen Beispiel anwenden wollen, müssen Sie vielleicht verschiedene Versionen davon schreiben (pinglaura, pingeric, pingelsa usw.). Es wäre sinnvoller, ein einzelnes allgemeines Skript zu schreiben und dann den Namen, den man prüfen will, als Parameter an das Skript zu senden.

Um Parameter (auch Argumente genannt) an ein Skript zu senden, spezifizieren Sie sie in der URL des Skripts mit einem Fragezeichen (?), das den Namen des Skripts von den Parametern trennt, und mit Pluszeichen (+), die alle individuellen Parameter voneinander trennen, so wie hier:

<A HREF="/cgi-bin/myScript?arg1+arg2+arg3">run my Script</A>

Wenn der Server die Anforderung des Skripts erhält, leitet er arg1, arg2 und arg3 an das Skript als Parameter weiter. Sie können diese Argumente dann aufteilen und im Inhalt des Skripts verwenden.

Diese Methode, Argumente an ein Skript weiterzuleiten, wird manchmal Anfrage (query) genannt, da Browser in früheren Versionen dieser Suchen, die ISINDEX-Suchen genannt wurden, auf diese Weise Suchschlüssel weitergeleitet haben (darüber erfahren Sie später noch mehr). Heutzutage werden die meisten Suchen mit Formularen durchgeführt, trotzdem wird diese Form der Kodierung von Parametern noch angewandt; Sie sollten damit vertraut sein, wenn Sie CGI-Skripten öfters verwenden.

 

Übung 19.2: Prüfen, ob jemand online ist

Jetzt, wo Sie wissen, wie man Argumente an ein Skript weiterleitet, lassen Sie uns das pinglaura-Skript so modifizieren, daß es allgemeiner verwendet werden kann. Wir werden dieses Skript pinggeneric nennen.

Beginnen Sie mit dem Anfang des Skripts aus dem letzten Beispiel mit einem etwas unterschiedlichen Titel:

#!/bin/sh
echo "Content-type: text/html"
echo
echo "<HTML><HEAD>"
echo "<TITLE>Are You There?</TITLE>"
echo "</HEAD><BODY>"

Im vorigen Beispiel war der nächste Schritt, zu testen, ob ich online war. An dieser Stelle wird das Skript jetzt allgemein. Anstatt den Namen lemay direkt in das Skript einzufügen, benutzen Sie ${1}, wobei ${1} der erste Parameter ist, ${2} der zweite, ${3} der dritte usw.

ison='who | grep "${1}"'

 

Warum Extra-Anführungszeichen um das ${1}? Das dient dazu, ungezogene Menschen davon abzuhalten, Ihrem Skript falsche Parameter zu verpassen. Es ist eine Sicherheitsfrage, die ich in Kapitel 28, »Web-Server: Sicherheit und Zugriffskontrolle«, noch detailliert besprechen werde.

Jetzt muß nur das restliche Skript so angepaßt werden, daß es statt des im Code spezifizierten Namens das Argument verwendet:

if [ ! -z "$ison" ]; then
echo "<P>$1 is logged in"
else
echo "<P>$1 isn't logged in"
fi

Und jetzt noch die abschließenden HTML-Tags:

echo "</BODY></HTML>"

Nachdem das Skript nun vollständig ist, lassen Sie uns die HTML-Seite modifizieren, die das Skript aufruft. Das pinglaura-Skript wurde durch ein HTML-Link aufgerufen, und zwar folgendermaßen:

<A HREF="http://www.lne.com/cgi-bin/pinglaura">Is Laura Logged in?</A>

Die allgemeine Version wird auf ähnliche Weise aufgerufen, mit dem Argument am Ende der URL, wie hier (wobei diesmal eine Person namens John gesucht wird):

<A HREF="http://www.lne.com/cgi-bin/pinggeneric?john">Is John Logged in?</A>

Versuchen Sie es auf Ihrem eigenen Server, mit Ihrem eigenen Einlog-ID im URL des Skripts, um zu sehen, was für ein Ergebnis Sie erhalten.

Dem Skript weitere Informationen übergeben

Neben den an das Skript übergebenen Argumenten gibt es noch eine Möglichkeit, einem CGI-Skript Informationen mitzuteilen (und es handelt sich dabei immer noch nicht um Formulare). Die zweite Methode ist die sogenannte Pfadinformation. Sie wird für Argumente verwendet, die zwischen den verschiedenen Aufrufen des Skripts nicht verändert werden können, etwa der Name einer temporären Datei oder der Name einer Datei, die das Skript selbst angelegt hat. Wie Sie im nächsten Abschnitt, der sich mit Formularen beschäftigt, sehen werden, können die Argumente hinter dem Fragezeichen gemäß der Eingabe des Anwenders verändert werden. Die Pfadinformationen werden dazu verwendet, dem Skript weitere Informationen mitzuteilen (und Sie können sie tatsächlich für beliebige Zwecke nutzen).

 

Pfadinformation ist eine Methode, Informationen an ein CGI-Skript weiterzuleiten, wenn diese Informationen sich nicht so oft ändern wie die regulären Skript-Parameter. Pfadinformation bezieht sich oft auf Dateien auf dem Web-Server, wie z.B. Konfigurationsdateien, temporäre Dateien oder die Datei, die das Skript, um das es sich handelt, aufgerufen hat.

Um Pfadinformation zu verwenden, hängen Sie die Informationen, die Sie einfügen wollen, ans Ende des URL des Skripts, nach dem Skript-Namen, aber vor dem ? und dem Rest des Parameters, so wie im folgenden Beispiel:

http://myhost/cgi-bin/myscript/remaining_path_info?arg1+arg2

Wenn das Skript abläuft, werden die Informationen aus dem Pfad in die Umgebungsvariable PATH_INFO hineingesteckt. Sie können diese Informationen dann, wie Sie wollen, im Inhalt des Skripts verwenden.

Sagen wir mal, Sie hätten verschiedene Links von verschiedenen Seiten zum selben Skript. Sie könnten dann die Pfad-Information verwenden, um den Namen der HTML-Datei anzuzeigen, von der das Link ausging. Wenn Sie dann mit der Verarbeitung Ihres Skripts fertig sind und eine HTML-Datei zurücksenden, könnten Sie ein Link von dieser Datei zurück zur Seite einsetzen, von der Ihr Leser herkam.

 

Besondere Skriptausgaben erzeugen

In den paar Beispielen, die Sie bisher in diesem Kapitel erstellt haben, haben Sie Skripten geschrieben, die Daten ausgeben, und zwar meistens HTML-Daten, und dann wurden diese Daten zum Browser zwecks Interpretation und Darstellung geschickt.

Was aber, wenn Sie keinen neuen Datenstrom als Ergebnis einer Skript-Aktion versenden wollen? Was, wenn Sie statt dessen eine bereits existierende Seite laden möchten? Was, wenn Sie möchten, daß das Skript irgend etwas tut, aber gar nichts an den Browser zurückmeldet?

Keine Sorge, Sie können solche Sachen machen. Dieser Abschnitt beschreibt, wie's geht.

 

Mit einem anderen Dokument antworten

CGI-Ausgabe braucht kein Datenstrom zu sein. Manchmal ist es einfacher, dem Browser anzugeben, er solle zu einer anderen Seite gehen, die Sie auf Ihrem Server gespeichert haben (oder irgendeinem anderen Server; wie dem auch sei). Um diese Anweisung zu senden, verwenden Sie eine Zeile, die der folgenden ähnelt:


Location: ../docs/final.html

Die Location-Zeile wird anstelle der normalen Ausgabe verwendet; d.h. wenn Sie Location verwenden, brauchen Sie keinen Inhaltstyp zu bezeichnen und keine weiteren Daten für die Ausgabe zu erzeugen (tatsächlich können Sie gar keine anderen Daten in die Ausgabe einfügen). Wie bei der Content-type-Zeile müssen Sie jedoch auch auf die Location-Zeile eine Leerzeile folgen lassen.

Der Pfad-Name der Datei kann entweder ein vollständiger URL sein oder ein relativer Pfad-Name. Alle relativen Pfad-Namen sind hier relativ zum Ort des Skripts selbst.

Dieser hier sucht nach dem Dokument final.html in einem Verzeichnis namens doc eine Ebene oberhalb des aktuellen Verzeichnisses:

echo Location: ../docs/final.html
echo

Sie können Content-type- und Location-Ausgaben nicht kombinieren. Wenn Sie beispielsweise eine Standardseite ausgeben und dann noch verschiedene Inhalte am Ende der Seite anhängen wollen, dann müssen Sie den Content-type-Header benutzen und beide Teile selbst zusammenbauen. Bedenken Sie, daß Sie das Skript verwenden können, um eine lokale Datei zu öffnen und sie direkt ausgeben zu lassen, z.B. würde cat dateiname den Inhalt der Datei namens dateiname als Daten schicken.


Keine Antwort

Bisweilen mag es für CGI-Skripten angemessen sein, gar keine Ausgaben zurückzugeben. Manchmal wollen Sie einfach nur Informationen von den Lesern entgegennehmen. Sie wollen womöglich kein neues Dokument laden, weder durch die Ausgabe von Ergebnissen noch durch das Öffnen bereits vorhandener Dateien. Das Dokument, das zuvor auf dem Browser-Bildschirm angezeigt wurde, soll einfach so bleiben, wie es war.

Glücklicherweise ist es ziemlich einfach, so etwas zu bewerkstelligen. Anstelle eines Headers mit Content-type oder Location benutzen Sie die folgende Zeile (wie immer wieder mit einer Leerzeile danach):

Status: 204 No Response

Dieser Status-Header meldet dem Server (und dem Browser) einen Status-Code. Der besondere Status-Code 204 wird an den Browser weitergegeben, und der Browser sollte, wenn er weiß, was er damit machen soll, einfach gar nichts tun.

Sie brauchen, da Sie ja nicht wollen, daß der Browser irgend etwas damit macht, keine weiteren Ausgaben Ihres Skripts - einfach die eine Status-Zeile und eine Leerzeile. Selbstverständlich sollte Ihr Skript irgend etwas tun, denn weshalb sonst beschäftigen Sie sich überhaupt mit einem Skriptaufruf?

Obwohl der No Response-Code ein offizieller Teil der HTTP-Spezifikationen ist, wird er nicht immer von allen Browsern unterstüzt oder kann seltsame Resultate hervorbringen. Bevor Sie einen No Response-Header benutzen, sollten Sie mit verschiedenen Browsern experimentieren, um zu sehen, was für Resultate Sie bekommen können.

Skripte, die Formulare verarbeiten

Die meisten CGI-Skript-Anwendungen heutzutage sind für die Verarbeitung von Formular-Eingaben gedacht. Wenn Sie ein Skript direkt von einem Link aufrufen können Sie dadurch nur dieses Skript mit den direktkodierten Argumenten ausführen. Formulare hingegen erlauben es, eine beliebige Menge Informationen vom Leser in das Formular eintragen zu lassen, es zum Server zurückzuschicken und von einem CGI-Skript verarbeiten zu lassen. Es sind dieselben Skripte, und sie funktionieren genauso. Sie verwenden immer noch Inhaltstyp und Location-Header, um eine Antwort an den Browser zurückzuschicken. Es gibt jedoch einige Unterschiede darin, wie beispielsweise die CGI-Skripten aufgerufen werden und wie die Daten vom Browser zum Server gesendet werden.

Erinnern Sie sich, daß die meisten Formulare aus zwei Teilen bestehen: dem HTML-Layout des Formulars und dem CGI-Skript, das die Formulardaten verarbeitet. Das CGI-Skript wird durch Attribute der Formular-Kennung aufgerufen.

 

Formular-Layout und Formular-Skripten

Wie Sie gestern gelernt haben, besteht jedes Formular auf dem Web aus zwei Teilen: dem HTML-Code des Formulars, der im Browser abgebildet wird, und dem Skript, das sich auf dem Server befindet und den Inhalt des Formulars verarbeitet. Beide sind durch den HTML-Code miteinander verbunden.

Das <ACTION>-Attribut innerhalb der <FORM>-Kennung enthält den Namen des Skripts, das das Formular verarbeiten soll:

<FORM ACTION="http://www.myserver.com/cgi-bin/processorscript">

Zusätzlich zu diesem Verweis auf das Skript hat jedes Eingabefeld des Formulars (Textfelder, Options-Felder usw.) ein NAME-Attribut, welches das Formularelement benennt. Wenn die Formulardaten an das CGI-Skript weitergeleitet werden, das Sie durch ACTION bestimmt haben, werden die Namen der Tags und der Inhalt des Felds an das Skript in Form eines Name/Wert-Paars weitergeleitet. In Ihrem Skript können Sie dann den Inhalt (den Wert) jedes Felds bekommen, indem Sie sich auf den Namen dieses Felds beziehen.

 

GET und POST

Ein Aspekt von Formularen, den ich gestern nicht erwähnt habe (höchstens flüchtig), ist das Attribut METHOD. METHOD gibt die Methode an, mit der Formulardaten vom Browser zum Server und dann zum Skript geleitet werden. METHOD kann einen von zwei Werten annehmen, GET oder POST.

GET funktioniert so wie die CGI-Skripten, die Sie im vorigen Abschnitt kennengelernt haben. Die Formulardaten werden verpackt und ans Ende der URL angehängt, den Sie im ACTION-Attribut als Parameter bestimmt haben. Wenn Ihr ACTION-Attribut also folgendermaßen aussieht:

ACTION="/cgi/myscript"

und Sie die gleichen zwei Eingabe-Tags wie im vorigen Abschnitt verwenden, wird der endgültige URL, der vom Browser zum Server gesendet wird, wenn das Formular übermittelt wird, ungefähr so aussehen:

http://myhost/cgi-bin/myscript?username=Agamemnon&phone=555-6666

Beachten Sie, daß diese Formatierung sich etwas von den Argumenten unterscheidet, die Sie von Hand an das CGI-Skript weitergeleitet haben; dieses Format wird URL-Kodierung genannt und später in diesem Kapitel noch detailliert besprochen.

Wenn der Server Ihr CGI-Skript zur Verarbeitung Ihres Formulars ausführt, setzt er die Umgebungsvariable QUERY_STRING auf den gesamten Eintrag, der im URL hinter dem Fragezeichen steht.

POST macht fast dasselbe wie GET, außer daß es die Daten separat vom eigentlichen Aufruf des Skripts sendet. Ihr Skript erhält die Formulardaten dann über die Standardeingabe. (Einige Web-Server speichern sie statt dessen in einer temporären Datei, vor allem Unix-Server). Die Umgebungsvariable QUERY_STRING wird bei POST nicht verwendet.

POST stellt die sicherere Methode dar, insbesondere wenn Sie sehr viele Formulardaten erwarten. Bei der Verwendung von GET weist der Server der Variablen QUERY_STRING die kodierten Formulardaten zu, und möglicherweise gibt es Beschränkungen, wie viele Daten Sie in dieser Variablen ablegen können. Mit anderen Worten, wenn Sie sehr viele Formulardaten haben und GET verwenden, könnte es sein, daß Sie einige Daten verlieren.

Bei der Verwendung von POST können Sie beliebig viele Daten haben, weil diese als separater Stream geschickt und keiner Variablen zugewiesen werden.

 

URL-Kodierung

URL-Kodierung ist das Format, mit dem der Browser die Eingabe für das Formular packt, wenn er es an den Server sendet. Der Browser ermittelt alle Namen und Werte der Formulareingabe, kodiert sie als Name/Wert-Paare, übersetzt alle Zeichen, die nicht übertragen werden können, organisiert die Daten und sendet sie - abhängig davon, ob Sie GET oder POST verwenden - als Teil der URL oder separat über eine direkte Verknüpfung an den Server. In jedem Fall erreicht die Formularseite die Server-Seite (und damit in Ihrem Skript) als Kauderwelsch, das irgendwie so aussieht:

theName=Ichabod+Crane&gender=male&status=missing&headless=yes

Die URL-Kodierung unterliegt den folgenden Regeln:

Als erstes muß Ihr Skript also alle Daten dekodieren, so daß Sie sie besser verwalten können. Im nächsten Abschnitt lernen Sie mehrere Programme kennen, die zur Dekodierung der Formulareingabe verwendet werden können.

Da die Formular-Eingabe an Ihr Skript in dieser URL-kodierten Form weitergeleitet wird, müssen Sie sie selber dekodieren, bevor Sie sie verwenden können. Da die Dekodierung dieser Informationen jedoch eine gewöhnliche Aufgabe ist, gibt es dafür eine Menge Werkzeuge. Es gibt keinen Grund für Sie, Ihre eigenes Dekodierungsprogramm zu schreiben, wenn Sie nicht gerade etwas sehr Ungewöhnliches machen möchten. Die Dekodierungsprogramme, die bereits fertig zur Verfügung stehen, können diesen Job gut erledigen und ziehen vielleicht Dinge in Betracht, an die Sie nicht gedacht haben, z.B. wie Sie den Absturz Ihres Skripts verhindern können, wenn jemand etwas Seltsames in Ihr Formular eingegeben hat.

Ich habe weiter hinten in diesem Kapitel einige Programme für die Dekodierung von Formulareingaben aufgeführt, aber das Programm, das ich für die Beispiele in diesem Buch verwenden werde, heißt uncgi. Es dekodiert die Eingabe einer Formularübermittlung für Sie und erzeugt Umgebungsvariablen von den Namen/Wert-Paaren. Jede Umgebungsvariable hat denselben Namen wie der Name des Name/Wert-Paars, wobei das Prefix www_ davorgesetzt wird. Jeder Wert eines Name/Wert-Paars wird dann seiner entsprechenden Umgebungsvariablen zugeordnet. Wenn Sie z.B. ein Formular mit einem Namen darin hätten, der username lautet, wäre die resultierende Umgebungsvariable, die von uncgi erzeugt wird, www_username, und der dazugehörige Wert wäre, was auch immer der Leser in dieses Formularelement eingetippt hat. Nachdem Sie die Umgebungsvariablen haben, können Sie sie genauso testen, wie Sie es mit jeder anderen Variablen täten.

Sie können den Quellcode für uncgi unter http://www.hyperion.com/~koreth/uncgi.html erhalten. Kompilieren Sie uncgi mit den Instruktionen, die dem Quellcode beiliegen, installieren Sie es in Ihrem cgi-bin-Verzeichnis, und Sie können loslegen.

 

Übung 19.3: Sag mir Deinen Namen, Teil 2

Erinnern Sie sich an das Formular, das Sie gestern erzeugt haben, das Sie nach Ihrem Namen fragt? Lassen Sie uns das Skript erzeugen, das dieses Formular verarbeitet (das Formular wird noch mal in Abbildung 19.5 gezeigt, falls Sie es vergessen haben sollten). Mit diesem Formular würden Sie Ihren Namen eintippen und dann das Formular mit dem Submit-Button übermitteln.

Die Eingabe wird zum Skript gesandt, welches ein HTML-Dokument mit einer Hallo-Nachricht darin, die Ihren Namen enthält, zurücksendet (siehe Abbildung 19.7).

Was würde passieren, wenn Sie bei der Aufforderung »Sag mir Deinen Namen« nichts eingäben? Das Skript würde Ihnen die Antwort »Du hast keinen Namen?« senden (siehe Abbildung 19.6).

siehe Abbildung

Abbildung 19.5:
Das Formular »Who are you?«

siehe Abbildung

Abbildung 19.6:
Das Ergebnis des Namens-Formulars

siehe Abbildung

Abbildung 19.7:
Ein anderes Ergebnis

Verändern Sie den HTML-Code des Formulars

In den gestrigen Beispielen benutzten wir ein Testprogramm namens post-query als Skript, um das ACTION-Attribut der Formular-Kennung aufzurufen. Jetzt, da wir mit echten Skripten arbeiten, werden wir das Formular dahingehend modifizieren, daß es auf ein echtes CGI-Skript hinweist. Der Wert von ACTION kann ein vollständiger URL oder ein relativer Pfad-Name zu einem Skript auf Ihrem Server sein. So würde beispielsweise die folgende <FORM>-Kennung ein Skript namens form-name in einem cgi-bin-Verzeichnis eine Ebene über dem aktuellen Verzeichnis aufrufen:

<FORM METHOD="post" ACTION="../cgi-bin/form-name.cgi">
</FORM>

Wenn Sie uncgi benutzen, um Formular-Eingaben zu dekodieren, so wie ich es in den Beispielen hier tue, sehen die Dinge etwas anders aus. Damit uncgi richtig funktioniert, rufen Sie es zuerst auf und hängen dann den Namen des eigentlichen Skripts hintendran, als ob uncgi ein Verzeichnis wäre:

<FORM METHOD="post" ACTION="../cgi-bin/uncgi/form-name.cgi">
</FORM>

Abgesehen von dieser einen Veränderung brauchen Sie den HTML-Code für das Formular nicht anzurühren. Lassen Sie uns deshalb nun mit dem Skript weitermachen, das das Formular verarbeitet.

 

Das Skript

Das Skript, mit dem Sie die Formulareingabe verarbeiten, ist meistens ein CGI-Skript, genauso wie diejenigen, die Sie bisher in diesem Kapitel erzeugt haben. Es gelten dieselben Regeln für Content-type-Header und für das Zurücksenden der Daten zum Browser.

Der erste Schritt in einem Formular-Skript besteht darin, die Angaben zu dekodieren, die Ihrem Skript durch die POST-Methode übermittelt wurden. Da wir in unserem Beispiel jedoch uncgi benutzen, um die Formulareingabe zu dekodieren, ist dieser Teil der Arbeit bereits erledigt. Erinnern Sie sich, wie Sie uncgi in das ACTION-Attribut Ihres Formulars gesteckt haben, gefolgt vom Namen Ihres Skripts? Was dort passiert, ist folgendes: Wenn die Formulareingabe übermittelt wird, leitet der Server diese Eingabe zum uncgi-Programm weiter, welches dann die Formulareingabe für Sie dekodiert und danach Ihr Skript aufruft, wenn alles bereits dekodiert ist. Wenn also Ihr Skript beginnt, stehen alle Name/Wert-Paare bereits zu Ihrer Verfügung.

Lassen Sie uns fortfahren, indem wir die normalen CGI-Header und den HTML-Code, der die Seite einleitet, angeben:

echo Content-type: text/hvml
echo
echo "<HTML><HEAD>"
echo "<TITLE>Hello</TITLE>"
echo "</HEAD><BODY>"
echo "<P>"

Jetzt kommt das Kernstück des Skripts. Sie müssen sich mit zwei Verzweigungen abgeben: die eine weist den Leser darauf hin, daß er keinen Namen eingegeben habe, und die andere sagt »hallo«, wenn er es tut.

Der Wert des Elements theName, wie Sie das erste Textfeld in Ihrem Formular genannt haben, wird innerhalb der www_theName-Umgebungsvariablen angegeben. Indem Sie einen einfachen Bourne Shell Test verwenden (-z), können Sie herausfinden, ob diese Umgebungsvariable leer ist, und dann eine angemessene Antwort in die Ausgabe einfügen:

if [ ! -z "$WWW_theName" ]; then
echo "Hello, "
echo $WWW_theName
else
echo "You don't have a name?"
fi

Schließlich fügen Sie das letzte bißchen HTML-Code ein, um das »go back«-Link einzusetzen. Dieser URL zeigt auf den URL des originalen Formulars zurück (das hier name1.html heißt und sich in einem Verzeichnis oberhalb von cgi-bin befindet):

echo "</P><P><A HREF="../lemay/name1.html">Go Back</A></P>"
echo "</BODY></HTML>"

Und damit wären wir soweit! Mehr ist da nicht dran. Der schwierige Teil ist, zu lernen, wie man CGI-Skripten erzeugt; sie dann mit den Formularen zu verknüpfen, ist einfach. Auch wenn Sie vielleicht verwirrt sind und es nicht so ganz mitgekriegt haben, bleiben Sie dran; morgen können Sie noch einen ganzen Haufen Beispiele ansehen und durcharbeiten.

Problemlösungen

Im folgenden finden Sie einige der häufigsten Probleme mit CGI-Skripten und entsprechende Lösungsvorschläge.


CGI-Variablen

CGI-Variablen sind besondere Variablen, die in einer Umgebung verwendet werden, wenn ein CGI-Skript aufgerufen wird. Sie können alle diese Variablen in Ihr Skript einsetzen, wie Sie möchten. Tabelle 19.2 gibt eine Zusammenfassung dieser Variablen.

Tabelle 19.2: CGI-Umgebungsvariablen

Umgebungsvariable

Bedeutung

SERVER_NAME

Der Hostname oder die IP-Adresse, die angeben, wo das CGI-Skript ausgeführt wird.

SERVER_SOFTWARE

Der Servertyp, den Sie verwenden, beispielsweise CERN/3.0 oder NCSA/1.3.

GATEWAY_INTERFACE

Die CGI-Version auf dem Server. Für Unix-Server ist das CGI/1.1.

SERVER_PROTOCOL

Das vom Server ausgeführte HTTP-Protokoll. Das sollte HTTP/1.0 sein.

SERVER_PORT

Der TCP-Port, auf dem der Server läuft. Für Web-Server ist das in der Regel Port 80.

REQUEST_METHOD

POST oder GET, abhängig davon, wie das Formular übertragen wurde.

HTTP_ACCEPT

Eine Liste der Inhaltstypen, die der Browser direkt akzeptiert, und die im HTTP-Accept-Header definiert sind.

HTTP_USER_AGENT

Der Browser, der die Formularinformation abgesendet hat. Browserinformation enthält normalerweise den Browsernamen, die Versionsnummer sowie zusätzliche Informationen über die Plattform oder bestimmte Kapazitäten.

HTTP_REFERER

Das URL des Dokuments, von dem diese Formularübertragung gekommen ist. Nicht alle Browser senden diesen Wert, Sie sollten sich also nicht darauf verlassen.

PATH_INFO

Zusätzliche Pfadinformationen, die vom Browser über die Abfragemethode von GET in einem Formular gesendet werden.

PATH_TRANSLATED

Der systemspezifische Pfad-Name des in PATH_INFO enthaltenen Pfads.

Skript_NAME

Der Pfad-Name für dieses CGI-Skript, wie er in dem URL erscheint (beispielsweise /cgi-bin/thescript).

QUERY_STRING

Die Argumente für das Skript oder die Formulareingabe (falls mit GET gesendet wurde). QUERY_STRING enthält den gesamten Inhalt der URL hinter dem Fragezeichen.

REMOTE_HOST

Der Name des Hosts, der das Skript angefordert hat. Dieser Wert kann nicht gesetzt werden.

REMOTE_ADDR

Die IP-Adresse des Hosts, der das Skript angefordert hat.

REMOTE_USER

Der Name des Benutzers, der das Skript angefordert hat. Dieser Wert wird nur gesetzt, wenn die Server-Authentifizierung aktiviert ist.

REMOTE_IDENT

Wenn der Web-Server ident ausführt (ein Protokoll, das den angemeldeten Benutzer verifiziert) und das System, das das Formular oder das Skript angefordert hat, ebenfalls ident ausführt, enthält diese Variable den von ident zurückgegebenen Wert.

CONTENT_TYPE

In Formularen, die mit POST übertragen wurden, ist das in der Regel application/x-www-form-urlencoded. In Formularen, die Dateien hochladen, ist der Inhaltstyp multipart/form- data.

CONTENT_LENGTH

Für Formulare, die mit POST übertragen wurden, ist das die Anzahl der Bytes in der Standardeingabe.


Programme zum Dekodieren

Der wichtigste Unterschied zwischen einem einfachen CGI-Skript und einem CGI-Skript, das ein Formular verarbeitet, ist, daß Sie für das letztere eine Methode zur Decodierung der Daten benötigen, die Sie vom Formular in URL-kodiertem Format zurückerhalten. Weil das aber jeder muß, der CGI-Skripten zur Verarbeitung von Formularen verwendet, gibt es Programme, die es für Sie erledigen und die die Name/Wert-Paare in etwas umwandeln, mit dem Sie einfacher weiterarbeiten können. Ich bevorzuge zwei Programme: uncgi für universelle Aufgaben und cgi-lib.pl, eine Perl-Bibliothek, die Sie zu Rate ziehen können, wenn Sie Skripten in Perl schreiben. Sie können jedoch Ihre eigenen Programme schreiben, wenn Ihnen die hier erwähnten nicht ausreichen.

Es gibt auch Programme, die Daten dekodieren, die formularbasiert hochgeladen wurden, obwohl die Auswahl da nicht so groß ist. Am Ende dieses Abschnitts werde ich einige erwähnen, die ich dafür gefunden habe.

 

uncgi

uncgi von Steven Grimm ist ein C-Programm, das die Formulareingaben für Sie dekodiert. Informationen sowie den Quellcode für uncgi erhalten Sie unter http://www.hyperion.com/~koreth/uncgi.html.

Sie sollten uncgi im Verzeichnis cgi-bin installieren. Stellen Sie sicher, daß Sie Ihr Makefile entsprechend angepaßt haben, bevor Sie die Datei kompilieren, so daß es auf dieses Verzeichnis auf Ihrem System zeigt und Ihre Skripten gefunden werden.

Wenn Sie uncgi in einem Formular einsetzen wollen, müssen Sie das ACTION-Attribut im FORM-Tag leicht modifizieren. Statt Ihr CGI-Skript direkt in ACTION aufzurufen, rufen Sie uncgi auf, wobei der Name des Skripts an den Aufruf angehängt wird. Wenn Sie z.B. ein CGI-Skript namens sleep2.cgi aufrufen wollten, würden Sie normalerweise so verfahren:

<FORM METHOD=POST ACTION="http://www.myserver.com/cgi-bin/sleep2.cgi">

Wenn Sie uncgi verwenden würden, würde das so aussehen:

<FORM METHOD=POST ACTION="http://www.myserver.com/cgi-bin/uncgi/sleep2.cgi">

Das Programm uncgi ist ein ausgezeichnetes Beispiel für die Verwendung von Pfadinformationen. Das uncgi-Skript verwendet den Namen des aktuellen Skripts als Pfadinformation, um zu ermitteln, wie das Skript aufgerufen wird.

Das Programm uncgi liest die Formulareingabe entweder von der GET- oder von der POST-Eingabe aus (das wird automatisch ermittelt), decodiert sie und erzeugt einige Variablen mit demselben Namen, den auch Werte jedes NAME-Attributs haben, wobei www_ davorgesetzt wird. Wenn z.B. Ihr Formular ein Textfeld mit dem Namen derName enthielte, wäre die uncgi-Variable mit dem Wert für derName www_derName.

Wenn es in der Eingabe mehrere Name/Wert-Paare mit demselben Namen gibt, erzeugt uncgi nur eine Umgebungsvariable mit durch Doppelkreuze (#) getrennten Werten. Wenn die Eingabe beispielsweise die Name/Wert-Paare shopping=butter, shopping=milk und shopping=beer enthält, enthält die resultierende Umgebungsvariable FORM_shopping den Wert butter#milk#beer. Es bleibt Ihnen überlassen, diese Information in Ihrem Skript korrekt zu verarbeiten.

 

cgi-lib.pl

Das Paket cgi-lib.pl von Steve Brenner enthält eine Menge Routinen für die Sprache Perl, die Sie bei der Verwaltung von Formulareingaben unterstützen sollen. Es kann Eingaben von GET oder POST entgegennehmen und sie in eine Perl-Liste oder ein assoziatives (wechselseitiges) Array einfügen. Neuere Versionen können auch Dateien verarbeiten, die von Formularen hochgeladen wurden. Informationen über cgi-lib.pl (und den Quellcode) erhalten Sie unter http://www.bio.cam.ac.uk/cgi-lib. Wenn Sie Ihre Formulareingaben mit Hilfe von Perl verarbeiten wollen, sollten Sie sich die Bibliothek cgi-lib.pl unbedingt besorgen.

Um cgi-lib.pl zu verwenden, besorgen Sie sich den Quellcode unter der im letzten Abschnitt beschriebenen URL-Adresse und legen ihn in Ihrem Verzeichnis mit den Perl-Bibliotheken ab. Anschließend geben Sie in Ihrem Perl-Skript die folgende Zeile an:

require 'cgi-lib.pl';

um die Unterroutinen aus der Bibliothek in Ihr Skript aufzunehmen.

Es gibt zwar in cgi-lib.pl mehrere Unterroutinen für die Verwaltung von Formularen, aber die wichtigste davon ist ReadParse. ReadParse liest GET- oder POST-Eingaben und speichert die Name/Wert-Paare unverändert in einem assoziativen Perl-Array. Normalerweise wird es in Ihrem Perl-Skript etwa folgendermaßen aufgerufen:

&ReadParse(*in);

Dieses Beispiel verwendet den Arraynamen in, Sie können aber einen beliebigen Namen wählen.

Nachdem die Formulareingabe decodiert wurde, können Sie in Ihrem Perl-Skript die Name/Wert-Paare durch den Zugriff auf die Namenskomponente lesen und verarbeiten, etwa wie folgt:

print $in{'theName'};

Dieses Beispiel gibt den Wert des Paares mit dem Namen theName aus.

Wenn es mehrere Name/Wert-Paare mit demselben Namen gibt, trennt cgi-lib.pl die Werte im Array durch Nullzeichen (\0). Es bleibt Ihnen überlassen, diese Information in Ihrem Skript korrekt zu verarbeiten.

 

Dekodieren der Eingabe hochgeladener Dateien

Da das formularbasierte Hochladen von Dateien ein neueres Feature darstellt, das eine unterschiedliche Methode der Formulareingabe erfordert, gibt es nur wenige Programme, die für Sie die Eingabe dekodieren, die Sie von einem Formular erhalten, von dem aus lokale Dateien hochgeladen wurden.

Neuere Versionen von cgi-lib.pl kommen mit dem Hochladen von Dateien sehr gut zurecht, indem sie sie in assoziative Arrays kodieren, ohne daß Sie noch irgendetwas dazu tun müßten. Wenden Sie sich an die Homepage von cgi-lib.pl für zusätzliche Informationen: http://www.bio.cam.ac.uk/cgi-lib/.

Eine andere Bibliothek für die Behandlung von CGI-Daten in Perl 5 names CGI.pl, die Ihnen ebenfalls beim Hinaufladen von Dateien behilflich ist, finden Sie unter http://valine.ncsa.uiuc.edu/cgi_docs.html.

 

Formulareingaben selbst decodieren

Die meisten Leute überlassen die Decodierung von Formulareingaben einem der hier beschriebenen Programme. Falls Ihnen keines dieser Programme zur Verfügung steht, Ihr System diese Programme nicht unterstützt oder Sie glauben, Sie könnten ein besseres schreiben, finden Sie hier einige nützliche Informationen.

Als erstes sollte Ihr Decoder-Programm prüfen, ob die Formulareingabe mit der POST- oder der GET-Methode gesendet wurde. Das ist aber ganz einfach. Die CGI-Umgebungsvariable REQUEST_METHOD, die vom Server vor dem Aufruf Ihres Programms gesetzt wird, gibt an, welche Methode verwendet wurde und wie Sie weiterarbeiten sollten.

Wenn die Formulareingabe über die GET-Methode an den Server gesendet wird, wird sie in der Umgebungsvariablen QUERY_STRING abgelegt.

Wenn die Formulareingabe über die POST-Methode an den Server gesendet wird, wird sie über die Standardeingabe an Ihr Skript geschickt. Die Umgebungsvariable CONTENT_LENGTH gibt an, wie viele Bytes der Browser übertragen hat. Sie sollten in Ihrem Decoder sicherstellen, daß nur die in CONTENT_LENGTH enthaltene Anzahl an Bytes verarbeitet wird. Einige Browser schließen die Standardeingabe möglicherweise nicht für Sie ab.

Ein typisches Decoder-Skript geht folgendermaßen vor:

Wenn es mehrere Namensschlüssel mit unterschiedlichen Werten gibt, sollten Sie eine Methode bereithalten, all diese Werte aufzubewahren.

Sind Sie daran interessiert, den Input vom Dateihochladen zu dekodieren? Dann müssen Sie anders vorgehen. Vor allem wird die Eingabe, die Sie von solchen formularbasierten Dateiübertragungen bekommen, mit dem Standard von mehrteiligen MIME-Botschaften übereinstimmen, so daß Sie es mit vielen verschiedenen Datentypen zu tun haben. Wenn Sie das interessiert, sollten Sie sich die Spezifikationen für formularbasiertes Hochladen von Dateien ansehen, die mehr Einzelheiten erklären werden. Sie finden diese Angaben unter ftp://ds.internic.net/rfc/rfc1867.txt.

Non-processed Header-Skripts - (NPH-Skripts)

Wenn Sie den in diesem Abschnitt vorgestellten Grundregeln beim Schreiben eines CGI-Skripts gefolgt sind, wird die Ausgabe Ihres Skripts (Header und gegebenenfalls Daten) vom Server gelesen und über das Netzwerk an den Browser zurückgeschickt. In den meisten Fällen ist das so in Ordnung, weil der Server alle notwendigen Überprüfungen ausführen und Ihren Headern seine eigenen hinzufügen kann.

In einigen Fällen will man jedoch den Server umgehen und die Ausgabe direkt an den Browser senden. Das könnte zum Beispiel sein, wenn Sie die Ausgabe an den Browser beschleunigen wollen oder wenn Daten an den Browser geschickt werden sollen, die der Server nicht versteht. Bei den meisten Formularen und CGI-Skripten brauchen Sie jedoch kein Skript, das dies tut.

CGI-Skripten für diesen Zweck heißen NPH-Skripts (non-processed headers, nichtausgewertete Header). Wenn Sie ein NPH-Skript benötigen, ändern Sie einfach Ihr normales Skript leicht ab:

Die Header stellen die offensichtlichste Veränderung dar, die Sie an Ihrem Skript vornehmen müssen. Insbesondere sollte der erste ausgegebene Header ein HTTP/1.0-Header mit einem Statuscode sein, etwa folgendermaßen:

HTTP/1.0 200 OK

Dieser Header mit dem Statuscode 200 bedeutet »alles in Ordnung, die Daten sind unterwegs«. Ein anderer möglicher Statuscode wäre

HTTP/1.0 204 No Response

Wie Sie in diesem Abschnitt bereits erfahren haben, heißt das, daß keine Daten von Ihrem Skript zurückgeschickt werden, der Browser also keine Aktion ausführen soll (etwa den Versuch, eine neue Seite zu laden).

Als zweiten Header sollten Sie wahrscheinlich den Server-Header aufnehmen. Es gibt gewisse Unstimmigkeiten darüber, ob dieser Header wirklich erforderlich ist, aber auf alle Fälle ist es nicht schlecht, ihn aufzunehmen. Schließlich geben Sie durch die Verwendung eines NPH-Skripts vor, ein Server zu sein, dann kann es nicht schaden, diesen Header zu verwenden.

Der Server-Header gibt einfach nur die Version des ausgeführten Servers an, wie im folgenden Beispiel gezeigt:

Server: NCSA/1.3
Server: CERN/3.0pre6

Nach diesen beiden Headern folgen alle anderen Header, die für Ihr Skript notwendig sind, unter anderem für Inhalt und Position. Der Browser benötigt diese Informationen immer noch, damit er verstehen kann, wie er die gesendeten Daten behandeln soll.

Auch hier gilt, daß Sie die NPH-Skripten größtenteils nicht brauchen. Normale CGI-Skripten sollten in der Regel ausreichend sein.

 

<ISINDEX>-Skripten

Um die Diskussion über CGI abzuschließen, lassen Sie uns über das reden, was <ISINDEX>-Suche genannt wird. Die Verwendung des <ISINDEX>-Tags war die Methode, mit der Browser in den Anfangszeiten des Web Informationen (meistens Suchschlüssel) an den Server sendeten. Suchen mit <ISINDEX> kommt heutzutage fast nicht mehr vor; statt dessen werden Formulare angewendet, da diese viel flexibler sowohl im Layout als auch in der Verschiedenheit ihrer Elemente und in den zu ihrer Verarbeitung anwendbaren Skripten sind. Da ich aber eine Vollständigkeitsfanatikerin bin, werde ich hier auch noch eine kurze Beschreibung der Funktionsweise von <ISINDEX>-Suchen geben.

<ISINDEX>-Suchen sind CGI-Skripte, die Argumente annehmen, genauso wie die Skripte, die Sie bereits in diesem Kapitel geschrieben haben, um herauszufinden, ob jemand online war. Das CGI-Skript für eine <ISINDEX>-Suche funktioniert auf zwei Arten:

Was macht <ISINDEX> also? Es schaltet die Suche in dem Browser ein, der das entsprechende Dokument liest. Je nach Browser kann dies das Erscheinen eines Such-Buttons im Browser-Fenster zur Folge haben (siehe Abbildung 19.8). Bei neueren Browsern kann es das Auftauchen eines Eingabefelds auf der Seite bewirken (siehe Abbildung 19.9). Der Leser kann dann die Zeichenfolge eingeben, nach der er sucht, und danach die Eingabetaste drücken oder den Button anklicken, um die Anfrage an den Server zu übermitteln.

siehe Abbildung

Abbildung 19.8:
Eine Suchaufforderung im Browser-Fenster

siehe Abbildung

Abbildung 19.9:
Eine Suchaufforderung auf der HTML-Seite

Gemäß den HTML-2.0-Spezifikationen gehört das <ISINDEX>-Tag in die <HEAD>-Sektion des HTML-Dokuments (es ist eines der wenigen Tags, das in den Kopfteil gehört - <TITLE> ist das andere offensichtliche Beispiel). In älteren Browsern, wo es nur einen einzigen Ort für die Suchaufforderung gab, ergab dies Sinn, da weder die Suchaufforderung noch das <ISINDEX>-Tag ein Teil der eigentlichen Daten des Dokuments war. Da jedoch neuere Browser das Eingabefeld auf der HTML-Seite selber darstellen, ist es nützlich, wenn man <ISINDEX> in den Inhaltsteil des Dokuments stecken kann, so daß man kontrollieren kann, wo auf der Seite das Eingabefeld erscheint (wenn es sich im <HEAD> befindet, wird es ganz oben auf der Seite dargestellt). Die meisten Browser akzeptieren das <ISINDEX>-Tag inzwischen an beliebigen Stellen innerhalb eines HTML-Dokuments und werden auch das Eingabefeld dort erscheinen lassen, wo das Tag sitzt.

Schließlich gibt es eine HTML-Erweiterung zum <ISINDEX>-Tag, die inzwischen Bestandteil von HTML 3.2 ist und es Ihnen erlaubt, die Suchaufforderung zu definieren. Auch hier gab es bei älteren Browsern eine Einschränkung: Die Suchaufforderung war unveränderbar (es war meistens etwas ähnlich Verwirrendes wie: »This is a searchable index. Enter keywords.«). Mit dem neuen PROMPT-Attribut zu <ISINDEX> können Sie die Zeichenfolge festlegen, mit der das Eingabefeld angezeigt wird, so wie im folgenden Codebeispiel. Abbildung 19.10 zeigt das Ergebnis dieses Tags in Netscape.

<P> To search for a student in the online directory,
enter the name (last name first):
<ISINDEX PROMPT="Student's name: ">

siehe Abbildung

Abbildung 19.10:
Eine Netscape-Suchaufforderung

<ISINDEX> ist nur im Zusammenhang mit einer ISINDEX-Suche nützlich. Obwohl Sie es in jedes beliebige HTML-Dokument stecken können, wird es wirkungslos bleiben, wenn diese Seite nicht ursprünglich von einem CGI-Skript erzeugt wurde.

Meistens ist es eine wesentlich einfachere Methode, den User um Informationen zu bitten, nämlich HTML-Formulare zu erzeugen.

Zusammenfassung

Gateway-Skripten, manchmal auch Server-Skripten oder CGI-Skripten genannt, ermöglichen es, Programme auf dem Server ablaufen zu lassen und dabei »auf die Schnelle« HTML- oder andere Dateien zu erzeugen.

Dieses Kapitel behandelt die Grundlagen der Erzeugung von CGI-Skripten: sowohl einfache Skripte, als auch Skripten zur Verarbeitung von Formularen, einschließlich der speziellen Header, die Sie in Ihren Skripten verwenden, den Unterschied zwischen GET und POST bei der Formulareingabe und wie Sie die Informationen, die Sie von der Formulareingabe bekommen, dekodieren. Außerdem erhielten Sie Extrainformationen über Pfadinformation, URL-Kodierung, <ISINDEX>-Suchen und die verschiedenen CGI-Variablen, die Sie in Ihren CGI-Skripten verwenden können. An diesem Punkt sollten Sie dazu in der Lage sein, CGI-Skripten zu schreiben, um so gut wie alles zu erreichen.

Fragen und Antworten

Frage:

Was ist, wenn ich gar nicht programmieren kann? Kann ich trotzdem CGI-Skripten benutzen?

Antwort:

Wenn Sie über einen kommerziellen Internet-Anbieter Zugang zum Web haben, können Sie vielleicht von ihm Hilfe bei Ihren CGI-Skripten erhalten (gegen Gebühr, versteht sich). Doch wenn Sie ein wenig programmieren können, aber bei dem, was Sie tun, unsicher sind, so gibt's üblicherweise als Teil der Server-Distribution oder an derselben FTP-Quelle viele Beispiele für die Plattform, auf der Sie arbeiten. Schauen Sie in die Dokumentation des Servers, mit dem Sie arbeiten; dort sind häufig Hinweise auf weitere Informationsquellen zu finden. Es könnte für die Operation, die Sie durchführen wollen, sogar schon ein fertiges Skript geben, das Sie mit wenigen Änderungen benutzen können. Seien Sie aber vorsichtig, Sie können schnell bis über den Hals in den Schlamassel geraten, wenn Sie nicht wissen, was Sie tun.

Frage:

Mein Web-Server besitzt ein cgi-bin-Verzeichnis, jedoch habe ich darauf keinen Zugriff. Deshalb erstellte ich mein eigenes cgi-bin-Verzeichnis und legte mein Skript dort hinein, konnte es jedoch nicht von meinen Webseiten her aufrufen. Was habe ich falsch gemacht?

Antwort:

Web-Server müssen auf spezielle Weise konfiguriert werden, um CGI-Skripten auszuführen, und das bedeutet meistens, daß bestimmte Verzeichnisse oder Dateien markiert werden müssen, die als Skripten agieren sollen. Sie können nicht einfach ein Verzeichnis oder eine Datei mit einer speziellen Erweiterung erzeugen, ohne zu wissen, wie Ihr Web-Master den Server konfiguriert hat; meistens werden Sie falsch liegen, und Ihre Skripten werden nicht funktionieren. Bitten Sie Ihren Web-Master bei der Installation Ihrer Skripten um Hilfe.

Frage:

Mein Web-Master behauptet, ich könne einfach ein cgi-bin-Verzeichnis in meinem Home-Verzeichnis erzeugen, meine Skripten dort installieren und sie dann mit einer speziellen URL namens cgiwrap aufrufen. Sie haben diese Art persönlicher cgi-bin-Verzeichnisse nicht erwähnt.

Antwort:

cgiwrap  ist ein hübsches Programm, das eine sichere Umhüllung für CGI-Skripten bietet und es Anwendern von öffentlichen Unix-Systemen ermöglicht, ihre eigenen persönlichen CGI-Verzeichnisse zu besitzen. Ihr Web-Master muß cgiwrap jedoch speziell für Ihren Server einrichten und konfigurieren, bevor Sie es anwenden können. Herzlichen Glückwunsch, wenn Ihr Web-Master die Verwendung von cgiwrap erlaubt hat. Dann werden CGI-Skripten für Sie leicht zu installieren und anzuwenden sein. Wenn Sie selbst der Web-Master sind und mehr herausfinden möchten, besuchen Sie http://wwwcgi.umr.edu/~cgiwrap/.

Frage:

Meine Skripten funktionieren nicht!

Antwort:

Haben Sie den Abschnitt über Problemlösungen mit den Fehlermeldungen und ihren möglichen Abhilfen durchgesehen? Ich habe dort die meisten gewöhnlichen Probleme, die auftreten können, behandelt.

Frage:

Mein Web-Anbieter will mir keinen Zugriff auf das cgi-bin-Verzeichnis erlauben. Absolut unter keinen Umständen. Ich möchte aber unbedingt Formulare verwenden. Gibt es da noch irgendeine Möglichkeit?

Antwort:

Es gibt noch eine Möglichkeit; sie heißt Mailto-Formular. Bei Mailto-Formularen benutzen Sie einen Mailto-URL mit Ihrer E-Mail-Adresse im ACTION-Teil des Formulars, und zwar folgendermaßen:

<FORM METHOD=POST ACTION="mailto:lemay@lne.com"> ... </FORM>


Frage:

Ich schreibe ein Decoder-Programm für die Formulareingabe. Das letzte Name/Wert-Paar in meiner Liste enthält lauter Müll.

Antwort:

Lesen Sie wirklich nur die Anzahl der Bytes aus, die in der Umgebungsvariablen CONTENT_LENGTH  angegeben sind? Prüfen Sie diesen Wert ab, und beenden Sie das Auslesen, wenn Sie das Ende erreicht haben, um nicht zu weit zu lesen. Nicht alle Browser schließen die Standardeingabe für Sie ab.


Copyright ©1998 by SAMS, einem Imprint der Markt&Technik Buch- und Software-Verlag GmbH.
Elektronische Fassung des Titels: HTML 4 in 14 Tagen, ISBN: 3-8272-2019-X


vorheriges KapitelTop Of PageInhaltsverzeichnisIndexInfoseitenächstes Kapitel