Das CGI-Modul gehört seit der Perl-Version 5.004 zu den Standardmodulen. Es stellt eine Menge Funktionen bereit, die typische Routine-Aufgaben von CGI-Scripts übernehmen. Die enthaltenen Funktionen sind durch vielfachen Praxiseinsatz bewährt. Es ist deshalb sinnvoll, für CGI-Scripts auf die Ressourcen zurückzugreifen, die dieses Modul bereitstellt. Ein Nachteil des CGI-Moduls ist allerdings, dass es recht groß ist. Bei CGI-Scripts, die sehr häufig aufgerufen werden (z.B. Zugriffszähler-Scripts auf vielbesuchten Seiten), kann sich das bei der Belastung des Server-Rechners bemerkbar machen. In solchen Fällen ist es durchaus vertretbar, sich bewusst gegen die Verwendung des CGI-Moduls zu entscheiden. Bei den meisten CGI-Scripts ist die Verwendung des CGI-Moduls jedoch zu empfehlen. Denn das Modul übernimmt unter anderem auch eine ganze Reihe von automatischen Anpassungen an die Laufumgebung des Scripts, durch die mögliche Fehler vermieden werden.
Das CGI-Modul besteht aus einem Hauptmodul und verschiedenen Untermodulen. Die Untermodule leisten spezielle Aufgaben wie beispielsweise die Unterstützung des neueren Fast-CGI-Standards oder die Unterstützung so genannter Server-Pushs.
Es gibt zwei Verwendungsweisen des CGI-Moduls: eine objektorientierte und eine funktionsorientierte. Die objektorientierte Verwendungsweise gilt als eleganter und bietet mehr Möglichkeiten, wie etwa das Definieren mehrerer unabhängiger CGI-Objekte im gleichen Script. Deshalb beschränken sich die Beschreibungen in diesem Abschnitt auf die objektorientierte Verwendung.
Das folgende Beispiel zeigt, wie Sie das CGI-Modul in einem eigenen Perl-Script einbinden und im objektorientierten Stil verwenden.
Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)
#!/usr/bin/perl -w use CGI; use CGI::Carp qw(fatalsToBrowser); $cgi = new CGI; print $cgi->header('text/plain'), "Hallo Welt";
Mit use CGI
binden Sie das CGI-Modul in Ihr Script ein. Im Beispiel wird aber noch ein Untermodul namens CGI::Carp
eingebunden, genauer, eine bestimmte Funktion daraus, nämlich die Funktion fatalsToBrowser
. Beim Entwickeln von CGI-Scripts ist es immer sinnvoll, dies mit einzubinden. Die Funktion bewirkt nämlich, dass alle Fehlermeldungen, die der Perl-Interpreter erzeugt, direkt im Browser ausgegeben werden.
Nachdem das CGI-Modul eingebunden ist, wird mit $cgi = new CGI
eine neue Instanz des CGI-Objekts erzeugt. Mit dieser Anweisung stellen Sie die Weichen dafür, das CGI-Modul objektorientiert zu verwenden. Die Objektinstanz der CGI-Klasse ist nun über den Skalar $cgi
ansprechbar. Über den Skalar haben Sie im weiteren Verlauf des Scripts Zugriff auf die Funktionen, die das CGI-Modul bereitstellt. Im objektorientierten Zusammenhang redet man dann jedoch nicht mehr von Funktionen, sondern von Methoden.
Der Name des Skalars, der im Beispiel $cgi
lautet, ist frei wählbar. Da Sie den Skalar im weiteren Verlauf des Scripts jedoch meistens sehr oft brauchen, empfiehlt sich ein kurzer Name. Viele Programmierer arbeiten mit einbuchstabigen Namen wie z.B. $q
.
Das obige Beispiel gibt ein einfaches "Hallo Welt" aus. Wie immer muss zur Übergabe an einen aufrufenden Browser zuerst ein HTTP-Header erzeugt werden. Das CGI-Modul stellt dafür eine Funktion bzw. Methode namens header()
zur Verfügung. Wenn dieser Methode kein Argument übergeben wird, erzeugt sie einen HTTP-Header für den MIME-Typ text/html
, also für die Ausgabe von HTML-Code. Im obigen Beispiel soll jedoch unformatierter Text gesendet werden. Deshalb wird der Funktion der MIME-Typ text/plain
übergeben.
An dem Beispiel des Aufrufs von header()
können Sie sehen, wie der Zugriff über den zuvor definierten Skalar funktioniert. Nach dem Schema $Skalar->Methode
"zeigen" Sie auf die Methode, und zwar mit dem Skalar, der an eine bestimmte, zuvor erzeugte Instanz des CGI-Objekts gebunden ist.
Zum Senden des HTTP-Headers und des auszugebenden "Hallo Welt" wird im Beispiel die übliche print-Funktion von Perl verwendet. Diese Funktion kann ja mehrere durch Komma getrennte Argumente gleichzeitig ausgeben. Im Beispiel gibt sie zuerst den Rückgabewert der Methode header()
aus, also den gewünschten HTTP-Header, und danach den Text Hallo Welt
.
Das CGI-Modul stellt eigene Methoden bereit, um HTML-Code zusammenzustellen.
Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)
#!/usr/bin/perl -w use strict; use CGI; my $cgi = new CGI; use CGI::Carp qw(fatalsToBrowser); my $Autor = "der Reiseonkel"; $cgi->default_dtd('-//W3C//DTD HTML 4.01 Transitional//EN'); print $cgi->header(), $cgi->start_html('Reisebericht vom Cap Ferret'), $cgi->h1('Reisebericht vom Cap Ferret'), $cgi->p('Die größte Sanddüne Europas mit 117m Höhe sieht man bei klarem Wetter, wenn man am Ufer des Beckens von Arcachon steht. Das Cap Ferret selbst ist ein kleiner Landzipfel, der vor allem aus Ferienhäusern besteht. Austernzucht, Fischerei und Wassersport prägen die Atmosphäre Becken von Arcachon.'), $cgi->hr({-noshade => undef, -size => '1'}), $cgi->p({-style => 'color:red'}, "Autor: ", $cgi->i($Autor)), $cgi->end_html();
Zunächst wird das CGI-Modul wie üblich mit use CGI
eingebunden. Um es im objektorientierten Stil zu verwenden, wird mit $cgi = new CGI
eine neue Instanz des CGI-Objekts erzeugt. Das Beispiel tut nichts anderes, als eine kleine vollständige HTML-Datei zusammenzustellen. Zunächst wird mit $cgi->header()
der HTTP-Header für HTML erzeugt. Dann folgt der HTML-Code.
Der HTML-Code wird jedoch nicht wie üblich notiert, sondern durch Aufruf von Methoden, die das CGI-Modul bereitstellt. Für alle gängigen HTML-Elemente und HTML-Tags gibt es solche Methoden. Dabei können Sie entweder das komplette HTML-Element erzeugen, oder auch nur ein Start- oder End-Tag. Die Anweisung $cgi->h1('Reisebericht vom Cap Ferret')
erzeugt beispielsweise ein komplettes HTML-Element mitsamt Inhalt. Der erzeugte Code lautet <h1>Reisebericht vom Cap Ferret</h1>
. Auf die gleiche Weise funktioniert es mit den anderen HTML-Elementen. $cgi->b('wichtiger Text')
würde beispielsweise den HTML-Code <b>wichtiger Text</b>
erzeugen.
Mit der Methode default_dtd
können Sie den DTD-Bezeichner festlegen, um das ausgegebene Dokument standardkonform gestalten zu können.
Die Überschrift im Beispiel könnte aber auch folgendermaßen notiert werden:
$cgi->start_h1(),"Reisebericht vom Cap Ferret",$cgi->end_h1()
.
Neben den kompletten Element-Methoden gibt es also auch Methoden, die nur ein einleitendes oder schließendes HTML-Tag erzeugen. $cgi->start_h1()
erzeugt also nur den HTML-Code <h1>
, und $cgi->end_h1()
den Code </h1>
. Entsprechende Methoden gibt es für alle Elemente, also beispielsweise auch $cgi->start_b()
und $cgi->end_b()
.
Die Verwendung von Methoden für öffnende und schließende Tags ist dann sinnvoll, wenn die Tags weit auseinanderliegen und sehr viel Inhalt haben. Vor allem bei <html>...</html>
ist das natürlich der Fall, denn dazwischen steht ja die komplette HTML-Datei. Die Methode $cgi->start_html()
, die auch im obigen Beispiel verwendet wird, hat jedoch eine Sonderstellung. Sie erzeugt nicht nur ein einleitendes <html>
-Tag, sondern schreibt auch den Standard-Dateikopf der HTML-Datei mit den Elementen head
und title
. Das Argument, das ihr übergeben wird, schreibt sie als Inhalt des title
-Elements.
Viele einleitende HTML-Tags haben Attribute. Um diese vom Inhalt des Elements zu unterscheiden, bieten die Methoden eine besondere Syntax an. Am obigen Beispiel ist das etwa bei der Trennlinie erkennbar. Mit der Anweisung: $cgi->hr({-noshade => undef, -size => '1'})
wird der HTML-Code <hr noshade size="1">
erzeugt. Das Argument, das der Methode übergeben wird, muss dazu in geschweiften Klammern {
bzw. }
stehen. Jedes Attribut wird durch ein Minuszeichen -
eingeleitet. Wertzuweisungen an Attribute werden durch den Operator =>
vom Attribut getrennt. Mehrere Attribute werden wie im hr
-Beispiel innerhalb der geschweiften Klammern durch Kommata getrennt.
Die Methoden zum Erzeugen von HTML-Elementen können auch mehrere Argumente übergeben bekommen. Dabei müssen Sie die Argumente durch Kommata trennen. Ein komplexeres Beispiel sehen Sie an der letzten $cgi->p(...)
-Anweisung. Dieser Methodenaufruf übergibt drei Argumente. Das erste Argument ist ein Attribut für das einleitende <p>
-Tag, nämlich ein style
-Attribut, in dem die Schriftfarbe rot bestimmt wird. Das zweite Argument ist statischer Text, und das dritte Argument zeigt gleich zwei weitere Möglichkeiten: es enthält einen weiteren Aufruf einer Element-Methode, nämlich $cgi->i()
für kursiven Text. Und als Argument wird dieser Methode kein statischer Text übergeben, sondern ein Skalar namens $Autor
, der weiter oben im Beispiel definiert wird.
Die Argumente erlauben also das bequeme Verschachteln von HTML-Elementen, ebenso wie das Einfügen von variablen Inhalten, die zuvor vom Script ermittelt wurden.
Das Einbinden des CGI-Moduls zwingt Sie keinesfalls dazu, HTML-Code auf diese Weise zu erzeugen. Sie können die HTML-Ausgaben auch direkt mit der print
-Funktion erzeugen oder zuvor eingelesene Templates ausgeben. Sie können auch Methodenaufrufe des CGI-Moduls mit herkömmlicher HTML-Code-Erzeugung mischen. Es ist also kein Problem, Mischformen wie diese zu notieren:
print "<hr noshade size='1'>",
$cgi->p({-style => 'color:red'}, "Autor: <i>$Autor</i>");
Normalerweise werden alle HTML-Elementnamen innerhalb der Methoden klein geschrieben, also z.B. start_div()
, end_div()
oder div()
. Es gibt jedoch ein paar Ausnahmen, um Kollisionen mit gleichnamigen Sprachbestandteilen von Perl zu vermeiden. Die HTML-Elemente Tr
, Select
, Link
und Sub
beginnen mit Großbuchstaben, also etwa in einer Anweisung wie:
$cgi->Sub('tiefgestellter Text')
.
HTML-Kommentare können Sie mit der Methode comment()
setzen. So erzeugt die Anweisung:
$cgi->comment('derzeit nicht aktuell')
den HTML-Code:
<!-- derzeit nicht aktuell -->
.
HTTP-Header können manchmal Zusatzinformationen erfordern. Und was den HTML-Dateikopf betrifft, so kann dieser ebenfalls wichtige allgemeine Angaben zur HTML-Datei enthalten, z.B. Meta-Tags oder die Attribute zur Seitengestaltung im einleitenden <body>
-Tag.
Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)
#!/usr/bin/perl -w use strict; use CGI; my $cgi = new CGI; use CGI::Carp qw(fatalsToBrowser); $cgi->default_dtd('-//W3C//DTD HTML 4.01 Transitional//EN'); print $cgi->header(-type =>'text/html', -expires =>'+1h'), $cgi->start_html(-title =>'Testseite mit Link', -author =>'beispiel@example.org', -base =>'true', -target =>'_blank', -meta =>{'keywords' =>'TeamOne, Test', 'description'=>'ein kleiner Test mit einem Link'}, -style =>{'src'=>'/styles/formate.css'}, -BGCOLOR=>'#FFFFCC', -TEXT =>'#000000', -LINK =>'red', -VLINK =>'blue', -ALINK =>'black'), $cgi->p('ein kleiner Test mit einem ', $cgi->a({-href => 'http://www.selfhtml.org/'},'Link auf selfhtml.org')), $cgi->end_html();
Das Script bindet mit use CGI
das CGI-Modul ein und erzeugt mit $cgi = new CGI
eine neue Instanz des CGI-Objekts. Bei der HTML-Ausgabe, die es anschließend erzeugt, nutzt es verschiedene Möglichkeiten, um den HTTP-Header und die Daten im Kopf der HTML-Datei zu beeinflussen.
Sowohl der Methode header()
zum Erzeugen des HTTP-Headers als auch der Methode start_html()
zum Erzeugen des HTML-Dateikopfes können Sie mehrere Argumente übergeben. Beide Methoden kennen jeweils ein Standardargument: bei header()
ist dies der MIME-Typ, und bei start_html()
der Inhalt des title
-Elements. Deshalb können Sie diese Argumente ohne weiteres direkt angeben, also etwa in der Form header('text/plain')
oder start_html('Text des Titels')
. Bei Angabe von mehreren und weiteren Argumenten sollten Sie jedoch die oben gezeigte Syntax verwenden. Dabei besteht jedes Argument aus einem Parameternamen, eingeleitet durch ein Minuszeichen -
, einem Zeigeoperator =>
und dem gewünschten Wert. Die beiden nachfolgenden Tabellen listen mögliche Argumente auf.
Die folgende Tabelle listet auf, welche Angaben Sie zum HTTP-Header notieren können. Die Code-Beispiele der linken Spalte stellen nur den reinen Methodenaufruf von header()
dar.
Aufrufbeispiel | Erläuterung |
---|---|
header(-type=>'image/gif'); |
Mit -type können Sie den MIME-Typ des nachfolgenden Datenstroms bestimmen. Im Beispiel können Sie anschließend die binären Daten einer GIF-Grafik ausgeben (dazu vorher gegebenenfalls die Funktion binmode aufrufen!) |
header(-status=>'204 No response'); |
Mit -status können Sie eine HTTP-Statusmeldung an den Browser senden. Mit der Beispielanweisung (HTTP-Status 204) können Sie die Ausgabe weiterer Daten an den Browser verweigern. Beim Anwender bleibt die zuletzt angezeigte Seite am Bildschirm stehen. Sinnvoll beispielsweise, wenn der Anwender durch Klick auf einen Link ein Voting-Script anstößt, das ihn aber nicht am sofortigen Weiterlesen der Seite hindern soll. |
print $cgi->header(-expires=>'+120s'); |
Mit -expires können Sie bewirken, dass der Browser die HTML-Ausgabe für einen Mindestzeitraum in seinen Cache-Speicher übernimmt. Bei einem Reload der ausgegebenen Seite innerhalb des angegebenen Zeitraums ruft der Browser dann nicht mehr das Script auf, sondern holt den HTML-Code aus seinem Cache. Den Zeitraum geben Sie als Zahl mit voranstehendem Pluszeichen und einem nachgestellten Buchstaben für die Zeiteinheit an. Die Angabe '+30s' im Beispiel bedeutet "HTML-Code 30 Sekunden im Cache halten". Andere Zeiteinheiten sind m (Minuten), h (Stunden), d (Tage), M (Monate) und y (Jahr). Darüber hinaus sind absolute Zeitangaben im UTC-Format erlaubt, wie z.B. Friday, 08-Jun-2001 11:29:00 GMT+0100 . |
print $cgi->header(-cookie=>$Cookie); |
Mit -cookie können Sie einen Cookie aktivieren. Mehr dazu im Abschnitt Cookies verwalten mit dem CGI-Modul. |
print $cgi->header(-nph=>1); |
Mit diesem Befehl können Sie so genannte NPH-Scripts schreiben. NPH steht für no-parsed-header und bedeutet, dass das CGI-Script die nachfolgenden Daten direkt an den aufrufenden Browser sendet, ohne dass der Webserver etwas davon mitbekommt. Dies kann zu Performance-Gewinnen führen, und in einigen Fällen, etwa beim Einsatz des Microsoft IIS-Webservers, ist es sogar vorgeschrieben, den NPH-Modus zu verwenden. |
Die folgende Tabelle listet auf, welche Angaben Sie zum HTML-Dateikopf notieren können. Die Code-Beispiele der linken Spalte stellen nur den reinen Methodenaufruf von start_html()
dar.
Aufrufbeispiel | Erläuterung |
---|---|
start_html(-title=>'Titeltext'); |
Mit -title bestimmen Sie den Titel der HTML-Ausgabe. Das Beispiel erzeugt den folgenden HTML-Code:<TITLE>Titeltext</TITLE>
|
start_html(-author=>'beispiel@example.org'); |
Mit -author erzeugen Sie eine logische Beziehung zu einer E-Mail-Adresse. Das Beispiel erzeugt folgenden HTML-Code:<LINK REV=MADE HREF="mailto:beispiel%40example.org">
|
start_html(-base=>'http://example.org/'); |
Mit -base bestimmen Sie die Basisadresse der ausgegebenen HTML-Seite. Das Beispiel erzeugt folgenden HTML-Code:<BASE HREF="http://example.org/">
|
start_html(-target=>'dataframe'); |
Mit -target bestimmen Sie den Basis-Fensternamen für Links in der HTML-Ausgabe. Das Beispiel erzeugt folgenden HTML-Code:<BASE TARGET="dataframe">
|
start_html(-meta=>{'keywords'=>'HTML,CSS'}); |
Mit -meta können Sie Meta-Angaben notieren - jedoch nur solche, die in HTML vom Typ name sind, nicht solche, die vom Typ http-equiv sind. Mehrere Meta-Angaben gleichzeitig sind erlaubt. Jede einzelne Meta-Angabe muss in geschweiften Klammern stehen. Innerhalb der geschweiften Klammern folgt zunächst der Wert, der in HTML dem name -Attribut zugewiesen würde, gefolgt von dem Operator => und dem Wert, den Sie in HTML dem content -Attribut zuweisen würden. Das Beispiel erzeugt folgenden HTML-Code:<META NAME="keywords" CONTENT="HTML,CSS">
|
start_html(-BGCOLOR=>'#000000'); |
Mit allen anderen Argumenten, die mit einem Minuszeichen beginnen und keinen der anderen reservierten Namen wie -title oder -meta haben, bestimmen Sie Attribute, die ins einleitende <body> -Tag eingefügt werden. Das Beispiel erzeugt folgenden HTML-Code:<BODY BGCOLOR="#000000">
|
Viele CGI-Scripts werden über HTML-Formulare aufgerufen. Eine der wichtigsten Aufgaben des CGI-Moduls ist es deshalb, dem Script übergebene Formulardaten einzulesen und in bequemer Form zur Verfügung zu stellen. Das folgende Beispiel ist das gleiche wie das aus dem Abschnitt Beispiel für die Wechselwirkung zwischen HTML und CGI, diesmal jedoch unter Einsatz des CGI-Moduls.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Kommentarseite</title> </head> <body bgcolor="#E0E0E0" text="#000000"> <h1>Ihr Kommentar</h1> <form action="/cgi-bin/comments.pl" method="post"> <p>Name:<br><input size="40" maxlength="40" name="AnwenderName"></p> <p>Text:<br><textarea rows="5" cols="50" name="Kommentartext"></textarea></p> <p><input type="submit" value="Absenden"></p> </form> </body> </html>
#!/usr/bin/perl -w use strict; use CGI; my $cgi = new CGI; use CGI::Carp qw(fatalsToBrowser); my @Feldnamen = $cgi->param(); print $cgi->header(), $cgi->start_html('CGI-Feedback'), $cgi->h1('CGI-Feedback vom Programm ',$cgi->i('comments.pl')); foreach my $Feld (@Feldnamen) { print $cgi->b('Feldname: '), $Feld, $cgi->b(', Inhalt: '), $cgi->param($Feld), "<br>"; } print $cgi->end_html();
Die HTML-Datei enthält ein Formular, das im einleitenden <form>
-Tag beim action
-Attribut das CGI-Script comments.pl aufruft. Als Methode für die Datenübertragung wird im Beispiel post
gewählt. Die andere Methode, also get
, wäre ebenso möglich. Das CGI-Modul erkennt die Übertragungsmethode automatisch.
Das CGI-Script comments.pl liest einfach die übergebenen Daten ein und sendet sie HTML-formatiert zurück. Dazu bindet das Script zunächst mit use CGI
das CGI-Modul ein und erzeugt mit $cgi = new CGI
eine neue Instanz des CGI-Objekts. Anschließend ist über den Skalar $cgi
der Zugriff auf Methoden des CGI-Objekts möglich. Entscheidend für die Formularverarbeitung ist die Methode param()
, mit deren Hilfe sich das Script die übergebenen Daten abholen kann.
Bei der Methode param
kommt es darauf an, in welchem Kontext sie aufgerufen wird. Dementsprechend unterschiedlich ist ihr Rückgabewert. Im obigen Beispiel steht die Anweisung @Feldnamen = $cgi->param()
. Es handelt sich dabei also um einen Listenkontext, d.h. erwartet wird eine Liste als Rückgabewert. Bei dieser Art des Aufrufs liefert param()
sämtliche Feldnamen eines eingelesenen Formulars zurück. Es handelt sich um jene Namen, die im HTML-Formular bei der Definition der Formularfelder jeweils mit dem Attribut name
festgelegt wurden. Das Ermitteln aller Feldnamen in einer Liste ist insofern praktisch, als sich diese Namen später als Parameter an param()
übergeben lassen. In der HTML-Ausgabe des Scripts ist ein solcher Aufruf von param()
enthalten. Dort ist die Anweisung $cgi->param($Feld)
notiert. Wenn param()
ein Feldname als Parameter übergeben wird, liefert die Methode den zugehörigen Wert oder Inhalt des Feldes zurück. Der Kontext ist dann skalar. Im obigen Beispiel werden in der Schleife foreach $Feld (@Feldnamen)
der Reihe nach alle Feldnamen des Formulars durchlaufen. Mit $cgi->param($Feld)
kann dann auf den Inhalt des jeweils aktuellen Formularfeldes zugegriffen werden.
Die folgende Tabelle fasst die Aufrufmöglichkeiten von param()
noch einmal zusammen.
Aufrufbeispiel | Rückgabewert | Erläuterung |
---|---|---|
if($cgi->param()) |
Liste, im booleschen Kontext ausgewertet (true oder false ) |
Ein solcher Aufruf in Form einer if -Bedingung ermittelt, ob überhaupt Daten an das Formular übergeben wurden oder nicht. Dies ist sinnvoll, wenn ein Script aus mehreren verschiedenen Kontexten heraus aufgerufen werden kann und erst einmal feststellen muss, ob es Formulardaten erhalten hat oder nicht. Im if -Zweig könnten die Formulardaten eingelesen werden, und im else -Zweig könnten Anweisungen stehen für den Fall, dass keine Formulardaten übergeben wurden. |
$Wert = $cgi->param('AnwenderName') |
Skalar | Gibt den Wert oder Inhalt des Formularfeldes mit dem Namen AnwenderName zurück. Diese Form der Notation ist sinnvoll, wenn Sie als Script-Autor die Feldnamen übergebener Formulardaten kennen und direkt den Wert oder Inhalt des jeweiligen Feldes ermitteln möchten. |
@Namen = $cgi->param() |
Liste | Gibt sämtliche Feldnamen des Formulars zurück. |
$cgi->param($Namen[2]) |
Skalar | Gibt den Wert oder Inhalt des dritten Formularfeldes zurück ($Namen[0] wäre das erste Formularfeld), sofern zuvor mit @Namen = $cgi->param() die Feldnamen als Liste gespeichert wurden. |
@Zutaten $cgi->param('Zutat') |
Liste | Gibt den Wert oder Inhalt einer Formularfeldgruppe mit gleichen Namen zurück zurück - vor allem bei Checkboxen in HTML-Formularen ist diese Aufrufvariante wichtig. In der Liste @Zutaten stehen anschließend alle Zutaten, die ein Anwender in Checkbox-Elementen mit dem Attribut name="Zutat" angekreuzt hat. |
Häufig benötigt ein CGI-Script Informationen über seine Umgebung, z.B. über den Server, den aufrufenden Browser, oder über seinen eigenen Speicherort auf dem Server. Das CGI-Modul stellt zum Ermitteln solcher Daten verschiedene Methoden bereit. Viele der Methoden liefern einfach nur Einzelheiten aus der vordefinierten Variablen %ENV
.
Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)
#!/usr/bin/perl -w use strict; use CGI; my $cgi = new CGI; use CGI::Carp qw(fatalsToBrowser); $cgi->default_dtd('-//W3C//DTD HTML 4.01 Transitional//EN'); print $cgi->header(), $cgi->start_html('Umgebungsdaten'), $cgi->start_table({-border => '1'}), $cgi->Tr($cgi->th({-align => 'right'},'Script-URI:'), $cgi->td($cgi->url(-full => 1))), $cgi->Tr($cgi->th({-align => 'right'},'relative Script-URI:'), $cgi->td($cgi->url(-relative => 1))), $cgi->Tr($cgi->th({-align => 'right'},'Server-Software:'), $cgi->td($cgi->server_software())), $cgi->Tr($cgi->th({-align => 'right'},'Browser-Software:'), $cgi->td($cgi->user_agent())), $cgi->end_table(), $cgi->end_html();
Das Beispiel-Script bindet zunächst mit use CGI
das CGI-Modul ein und erzeugt mit $cgi = new CGI
eine neue Instanz des CGI-Objekts. Anschließend sendet es HTML-Code an den Browser, und zwar eine Tabelle mit ein paar Umgebungsinformationen. Die HTML-Ausgaben werden mit Hilfe der Methoden des CGI-Moduls und deren Regeln realisiert. Die ausgegebene Tabelle listet in der linken Spalte in einem th
-Element jeweils auf, welche Information die Zeile enthält, und in der rechten Spalte in einem td
-Element den zugehörigen Wert. Dieser Wert wird jeweils mit Methoden des CGI-Moduls ermittelt. So wird mit $cgi->url(-full => 1)
beispielsweise der URI des Scripts ermittelt.
Die folgende Tabelle listet verfügbare Methoden für Umgebungsdaten auf. Die Aufrufbeispiele gehen davon aus, dass mit $cgi = new CGI
eine Instanz des CGI-Objekts erzeugt wurde. Die Tabelle ist nach Methodennamen alphabetisch sortiert.
Methode | Rückgabewert | Erläuterung |
---|---|---|
$cgi->Accept() |
Liste | Ermittelt eine Liste der MIME-Typen, die der aufrufende Browser akzeptiert. Dies ist interessant abzuprüfen, bevor ein Script Daten eines nicht selbstverständlichen MIME-Typs an den Browser senden will. Es kann sein, dass die Liste nur aus einem Element mit dem Wert */* besteht. Dann akzeptiert der aufrufende Browser potentiell alle MIME-Typen. |
$cgi->auth_type() |
Skalar | Ermittelt den Typ der Benutzer-Authentifizierung, sofern das Script zugangsgeschützt und nur durch Eingabe entsprechender Zugangsdaten aufrufbar ist. |
$cgi->path_info() |
Skalar | Ermittelt zusätzliche, wie weitere Unterverzeichnisse notierte Angaben. Wenn das Script beispielsweise die Adresse http://meine.seite.net/cgi-bin/test.pl hat, aber mit http://meine.seite.net/cgi-bin/test.pl/querys/musicbase.sql aufgerufen wird, dann ermittelt dieser Befehl den Anteil /querys/musicbase.sql . Beachten Sie, dass Aufrufe dieser Art nicht von allen Webservern korrekt verarbeitet werden. |
$cgi->path_translated() |
Skalar | Ermittelt wie $cgi->path_info() zusätzliche, wie weitere Unterverzeichnisse notierte Angaben, jedoch mit dem Unterschied, dass nicht der Anteil aus dem URI zurückgegeben wird, sondern der vom Web-Server übersetzte Datenpfad dieses Anteils. Angenommen, das Script hat die Adresse http://meine.seite.net/cgi-bin/test.pl , wurde aber mit http://meine.seite.net/cgi-bin/test.pl/querys/musicbase.sql aufgerufen. Dann könnte der zusätzliche Adressanteil /querys/musicbase.sql aus Sicht des Web-Servers beispielsweise in einen physikalischen Pfadnamen wie /usr/web/seite/querys/musicbase.sql aufgelöst werden. Diesen Pfadnamen würde $cgi->path_translated() zurückgeben. |
$cgi->referer() |
Skalar | Ermittelt den URI der im Browser angezeigten Seite, von der aus das CGI-Script aufgerufen wurde. Ein solcher Wert lässt sich dann ermitteln, wenn das Script über ein abgesendetes Formular oder über einen Link aufgerufen wurde. |
$cgi->remote_host() |
Skalar | Ermittelt den Internetzugangs-Domainnamen (falls verfügbar) oder die Zugangs-IP-Adresse des aufrufenden Browsers. |
$cgi->remote_user() |
Skalar | Ermittelt den Benutzernamen, mit dem sich der aufrufende Benutzer angemeldet hat, um das CGI-Script aufzurufen. Wenn das Script beispielsweise htaccess-geschützt ist, muss sich der aufrufende Benutzer mit Benutzernamen und Passwort anmelden. Der dabei eingegebene Benutzername kann mit diesem Befehl ermittelt werden. |
$cgi->request_method() |
Skalar | Ermittelt die HTTP-Methode, mit der das CGI-Script aufgerufen wurde, gibt also üblicherweise GET oder POST zurück. |
$cgi->script_name() |
Skalar | Ermittelt den absoluten HTTP-Pfad des CGI-Scripts. Bei einem Script mit der Adresse http://meine.seite.net/cgi-bin/test.pl würde also /cgi-bin/test.pl ermittelt. Dieser Wert eignet sich sehr gut für weitere Selbstaufrufe des Scripts, etwa bei mehrseitigen Anwendungen wie Bestellvorgängen. |
$cgi->server_name() |
Skalar | Ermittelt den Namen des Server-Rechners, auf dem das CGI-Script läuft. Normalerweise ist dies der eingetragene Hostname des Rechners. |
$cgi->server_software() |
Skalar | Ermittelt den Namen und die Versionsnummer der Webserver-Software auf dem Server-Rechner. |
$cgi->url(-full => 1) |
Skalar | Ermittelt die vollständige Adresse des CGI-Scripts, aber ohne eventuell mit übergebene Parameter. |
$cgi->url(-path => 1) |
Skalar | Ermittelt zusätzliche, wie weitere Unterverzeichnisse notierte Angaben. Wenn das Script beispielsweise die Adresse http://meine.seite.net/cgi-bin/test.pl hat, aber mit http://meine.seite.net/cgi-bin/test.pl/data/musicbase aufgerufen wird, dann ermittelt dieser Befehl den Anteil /data/musicbase . Beachten Sie, dass Aufrufe dieser Art nicht von allen Webservern korrekt verarbeitet werden. |
$cgi->url(-query => 1) |
Skalar | Ermittelt die vollständige eigene Adresse des CGI-Scripts inklusive übergebener Parameter. Bei Aufrufen wie http://meine.seite.net/cgi-bin/test.pl?user=Heino&wunsch=Volksmusik wird also auch der Teil hinter dem Fragezeichen mit zurückgegeben. |
$cgi->url(-relative => 1) |
Skalar | Ermittelt den relativen HTTP-Pfad des CGI-Scripts aus Sicht des aktuellen Arbeitsverzeichnisses. |
$cgi->url_param() |
Liste | Ermittelt eine Liste aller Parameternamen, sofern Parameter übergeben wurden. Bei einem Script-Aufruf wie http://meine.seite.net/cgi-bin/test.pl?user=Heino&wunsch=Volksmusik wird also eine Liste mit den beiden Elementen user und wunsch ermittelt |
$cgi->url_param('wunsch') |
Skalar | Ermittelt den Wert eines dem Script übergebenen Parameter namens wunsch . Bei einem Script-Aufruf wie http://meine.seite.net/cgi-bin/test.pl?user=Heino&wunsch=Volksmusik wird also Volksmusik ermittelt. |
if($cgi->url_param()) |
Liste, im booleschen Kontext ausgewertet | Ermittelt, ob dem Script über den URI irgendwelche Daten übergeben wurden. Im if -Zweig könnten Anweisungen stehen, die auf diesen Fall reagieren, während im else -Zweig davon ausgegangen werden kann, dass keine Parameter übergeben wurden. |
$cgi->user_agent() |
Skalar | Ermittelt die Bezeichnung, mit der sich der aufrufende Browser dem Server gegenüber ausgewiesen hat. Typische ermittelte Werte sind solche wie Mozilla/4.0 (compatible; MSIE 5.5; Windows 98) (für den Internet Explorer 5.5). |
$cgi->user_name() |
Skalar | Ermittelt den Namen des aufrufenden Benutzers mit Hilfe verschiedener Abfragen. Moderne Browser verhindern allerdings ein Ausspionieren dieser Daten. |
$cgi->virtual_host() |
Skalar | Ermittelt den Domainnamen, mit dem der Browser das CGI-Script aufgerufen hat. |
Cookies sind kleine Informationseinheiten, die eine Webseite auf dem Rechner des aufrufenden Anwenders speichern kann. Das Speichern und Verwalten wird dabei vom Browser des Anwenders kontrolliert. Cookies erlauben es, anwender-individuelle Informationen wie den Zeitpunkt des letzten Besuchs oder angeklickte Angebote zu speichern und beim nächsten Aufruf wieder auszulesen. Das CGI-Modul unterstützt das Setzen und Lesen solcher Cookies.
#!/usr/bin/perl -w use strict; use CGI; my $cgi = new CGI; use CGI::Carp qw(fatalsToBrowser); my $CTIME_String = localtime(time); my $altCookie = $cgi->cookie(-name=>'letzter_Besuch'); my $neuCookie = $cgi->cookie(-name=>'letzter_Besuch', -value=>$CTIME_String, -expires=>'+3M', -path=>'/'); print $cgi->header(-cookie=>$neuCookie), $cgi->start_html("Cookie-Test"), $cgi->p("<b>Ihr letzter Besuchszeitpunkt dieser Seite war</b>: ", $altCookie || 'unbekannt'), $cgi->p("<b>Als neuer Besuchszeitpunkt wurde gespeichert</b>: ", $CTIME_String), $cgi->end_html();
Das Beispiel-Script verwendet einen Cookie, mit dessen Hilfe es den letzten Aufrufzeitpunkt ermitteln kann und den aktuellen Aufrufzeitpunkt als neuen letzten speichert. Zur Kontrolle erzeugt es eine HTML-Ausgabe, in der dem Besucher der eingelesene alte Aufrufzeitpunkt und der neu gespeicherte Aufrufzeitpunkt mitgeteilt wird. Dazu bindet das Script zunächst mit use CGI
das CGI-Modul ein und erzeugt mit $cgi = new CGI
eine neue Instanz des CGI-Objekts. Mit localtime(time) ermittelt es den aktuellen Zeitpunkt und speichert den Wert im Skalar $CTIME_String
. Das Lesen und Setzen des Cookies steuert die Methode cookie()
des CGI-Moduls. Über den Skalar $cgi
, der an das erzeugte CGI-Objekt gebunden ist, greift das Script mit $cgi->cookie()
auf die Methode zu.
Die Methode cookie()
erwartet Argumente. Je nachdem, welche Argumente ihr übergeben werden, liest sie einen vorhandenen Cookie oder definiert einen neuen. Alle Argumente bestehen aus einem Argumentnamen und einem Wert. Der Argumentname beginnt mit einem Minuszeichen -
. Hinter dem Argumentnamen folgt der Operator =>
und dahinter die Angabe des gewünschten Wertes.
Zum Lesen genügt es, das Argument -name
anzugeben. Ist ein Cookie mit diesem Namen vorhanden, dann liefert der Aufruf von cookie()
dessen Wert zurück. Genau das geschieht im ersten Aufruf des obigen Beispiels. Der zurückgegebene Wert wird dort im Skalar $altCookie
gespeichert. Im Beispiel hat das Cookie den Namen letzer_Besuch
.
Zum Setzen eines Cookies müssen Sie mindestens zwei Argumente an cookie()
übergeben, nämlich die Argumente -name
und -value
. Bei -value
geben Sie an, welcher Wert gespeichert werden soll. Im obigen Beispiel ist das der Inhalt des zuvor errechneten Skalars $CTIME_String
. Durch die Angabe von -value
wird das Cookie aber noch nicht gesetzt. Dies geschieht erst beim Senden eines HTTP-Headers an den aufrufenden Browser. Dazu wird zunächst der Rückgabewert des Aufrufs von cookie()
gespeichert, und zwar im Skalar $neuCookie
. Dieser Skalar wird dann beim HTTP-Header, den Sie mit der Methode header()
an den Browser senden, im Argument -cookie
als Wert gesendet, so wie im obigen Beispiel gezeigt.
Ein weiteres wichtiges Argument der Methode cookie()
ist -expires
. Damit geben Sie an, wie lange der Browser das Cookie beim Anwender speichern soll. Wenn Sie -expires
nicht angeben, behält der Browser das Cookie nur solange bis der Anwender den Browser beendet. Den gewünschten Speicherzeitraum geben Sie als Zahl mit voranstehendem Pluszeichen und einem nachgestellten Buchstaben für die Zeiteinheit an. Die Angabe '+3M'
im Beispiel bedeutet "3 Monate". Andere Zeiteinheiten sind s
(Sekunden), m
(Minuten), h
(Stunden), d
(Tage) und y
(Jahr). Darüber hinaus sind absolute Zeitangaben im UTC-Format erlaubt, wie z.B. Friday, 08-Jun-2001 11:29:00 GMT+0100
.
Die Methode cookie()
kennt daneben noch weitere Argumente. Mit -path
geben Sie den HTTP-Pfad auf dem Server an, für den (einschließlich seiner Unterverzeichnisse) das Cookie gelten soll. Fehlt die Angabe, dann gilt das Cookie für die gesamte Domain ab der Dokumentwurzel. Mit -domain
können Sie angeben, für welche Sub-Domain innerhalb der Hauptdomain das Cookie gelten soll (z.B. -domain => news.aufdiesemserver.de
). Mit -secure
, das als Wertzuweisung dann true
, also beispielsweise 1
erwartet, erreichen Sie, dass das Cookie nur dann gesetzt wird, wenn die Serverumgebung eine SSL-geschützte Umgebung ist. Das ist wichtig, wenn Sie sensible Daten im Cookie übertragen, etwa die Kreditkartennummer des Anwenders, um ihm diese bei seinem nächsten Besuch gleich als Vorbelegung eines Formularfeldes anzubieten.
Manche CGI-Scripts dienen dazu, den aufrufenden Anwender zu einer anderen Adresse weiterzuleiten und vorher eventuell noch ein paar Aufgaben zu erledigen.
#!/usr/bin/perl -w use strict; use CGI; my $cgi = new CGI; use CGI::Carp qw(fatalsToBrowser); open(FH,">>/usr/web/data/userlog.xml"); print FH "<user-call>\n <remote-host>", $cgi->remote_host(), "</remote-host>\n <user-agent>", $cgi->user_agent(), "</user-agent>\n <goto-url>", $cgi->url_param('goto'), "</goto-url>\n <time-stamp>", localtime(time), "</time-stamp>\n</user-call>\n"; close(FH); print $cgi->redirect($cgi->url_param('goto'));
Das Beispiel-Script erwartet beim Aufruf im URI einen Parameter namens goto
, dem wiederum eine gültige Adresse zugewiesen werden sollte. Angenommen, das Script hat die Adresse "http://localhost/cgi-bin/redirect.pl", dann wäre ein denkbarer Aufruf http://localhost/cgi-bin/redirect.pl?goto=http%3A%2F%2Fde.selfhtml.org/
. Ein solcher Aufruf könnte beispielsweise als href
-Attribut in einem Link stehen, der den Anwender eigentlich zu de.selfhtml.org führt, aber zuvor noch ein paar Daten über den Anwender sammelt.
Das Script bindet zunächst mit use CGI
das CGI-Modul ein und erzeugt mit $cgi = new CGI
eine neue Instanz des CGI-Objekts. Die Weiterleitung ist dann wie in der untersten Anweisung des Beispiels gezeigt mit print $cgi->redirect()
möglich. Als Argument wird der Methode redirect()
die gewünschte Adresse übergeben, zu der die Umleitung erfolgen soll. Im Beispiel wird keine statische Adresse übergeben, sondern der Wert, der aus der Umgebungsvariablen url_param('goto')
gewonnen wird. Darin ist der beim Script-Aufruf übergebene Wert von goto
enthalten. Das Script tut also aus Anwendersicht nichts weiter, als die übergebene Adresse aufzurufen.
Zuvor schreibt das Script jedoch einige Daten über den Anwender in eine XML-Datei. In diese Datei werden Daten wie Hostname oder IP-Adresse des Anwenders, sein Browser-Typ, die Umleitungsadresse und der aktuelle Zeitstempel, ermittelt mit localtime(time), geschrieben. Zum Öffnen und Schließen der Datei verwendet das Script die üblichen Perl-Funktionen open und close. Die Daten werden wie üblich mit print und Angabe des Datei-Handles (im Beispiel FH
) geschrieben.
Das CGI-Modul bietet zwei wichtige Einstellmöglichkeiten an, mit denen Sie die Sicherheit eines CGI-Scripts vor böswilliger Benutzung erhöhen können. Die beiden Befehle sollten Sie zu Beginn des Scripts notieren, jedoch nach dem Einbinden des CGI-Moduls mit use CGI
.
Befehl | Erläuterung |
---|---|
$CGI::POST_MAX = 1024 * 100; |
Mit diesem Befehl legen Sie fest, wie viele Daten maximal an das CGI-Script übertragen werden können. Im Beispiel wird eine byte-gerechte Zahl errechnet, nämlich 100 Kilobyte. Wird der Wert überschritten, wird die Parameterliste gelöscht. Der entsprechende Fehlercode wird von der Methode cgi_error zurückgegeben. |
$CGI::DISABLE_UPLOADS = 1; |
Mit diesem Befehl können Sie verhindern, dass Dateien, die via Formular an das Script übertragen werden, also HTML-Tags der Sorte <input type="file"> , automatisch in eine temporäre Datei gespeichert werden. Die entsprechenden Formulardaten werden dann beim Auswerten einfach übergangen. Interessant ist ein solcher Befehl beispielsweise, wenn das Script vorher nicht weiß, von wo es aufgerufen wird und welche Formulardaten es zu verarbeiten hat - etwa ein öffentlich zugänglicher Form-Mailer, der beliebige ausgefüllte HTML-Formulare an eine E-Mail-Adresse sendet. |
Computer und geschriebene Sprache | |
CPAN-Module | |
SELFHTML/Navigationshilfen Perl Perl-Module |
© 2005 Impressum