CGI: Datenübertragung zwischen HTML und CGI
Eine der wichtigsten Aufgaben von CGI ist die Datenverarbeitung von Nutzereingaben - also das Auswerten von HTML-Formularen. Andersherum müssen die Verarbeiteten Daten natürlich auch wieder an den Benutzer ausgegeben werden. Beides zeigen wir Ihnen hier.HTML-Formulare und Querystrings
Die Datenübertragung vom Browser an ein CGI-Skript beruht im Großen und Ganzen auf der Funktionsweise von CGI-Umgebungsvariablen. Sie wird letztendlich dadurch ermöglicht, dass einige dieser Variablen in der CGI-Schnittstelle einen Stringwert zugewiesen bekommen, der sich einem bestimmten Prinzip folgend aus den Inhalten beispielsweise von Formularfeldern oder Variablen zusammensetzt. Welche der Umgebungsvariablen davon betroffen sind, hängt von der Methode ab, wie die Daten an das CGI-Skript übertragen, d.h. in die CGI-Umgebung geschrieben, werden.Das Zusammenspiel von HTML-Formularen und CGI
Das HTTP-Protokoll stellt für die Übertragung von Formulardaten an das CGI im Wesentlichen zwei Methoden zur Verfügung:GET
und POST
. Die Methoden legt man im Attribut method
des form
-Elements fest.
Die GET-Methode
Bei dieser Methode werden die Formulardaten, eingeleitet durch ein Fragezeichen, mit Hilfe eines bestimmten Kodierungsprinzips derURIdes vom Formular aufgerufenen CGI-Skripts angefügt.Diese Zeichenfolge, der sogenannte Querystring, wird nun zunächst in die CGI-Schnittstelle des Servers übertragen und in der Umgebungsvariable
$ENV{"QUERY_STRING"}
gespeichert, deren Wert das CGI-Skript über das Verfahren zum Auslesen von Hashs in Perl erhält:
$Formulardaten = $ENV{"QUERY_SRING"};
Ein derartiger Querystring kann natürlich auch mittels JavaScript nach entsprechendem Kodierungsprinzip derURIangehangen werden, ohne dass dabei ein Formular zum Einsatz kommt. Diese Methodik findet sehr oft in Foren, etc. Anwendung.Die POST-Methode
Bei Anwendung dieser Methodik werden die Formulardaten direkt in die standardeingabeSTDIN
des aufgerufenen CGI-Skripts übertragen, welche das Script dann mittels einer speziellen Funktion ermitteln kann:
read(STDIN, $Formulardaten, $ENV{"CONTENT_LENGTH"};
Wie im Beispiel zu erkennen ist, wird hier an die standardfunktionread
u.a. wieder eine Umgebungsvariable als Parameter übergeben. Dies liegt daran, dass die in STDIN
geschriebenen Daten kein Zeichen enthalten, welches das Ende des Datenstroms kennzeichnet. Die Umgebungsvariable $ENV{"CONTENT_LENGTH"}
enthält daher die Anzahl der einzulesenden Zeichen aus der Standardeingabe.Der von der Funktion
read
zurückgegebene String trägt im Beispiel dann den Bezeichner $Formulardaten
.
Das Kodierungsprinzip
Die zu übertragenden Formulardaten müssen durch spezielle Zeichen voneinander getrennt werden, damit es im CGI-Skript später möglich ist, die einzelnen Daten separat zu ermitteln.Die Übertragung der beiden Inhalte
Inhalt1
und Inhalt2
der Formularfelder mit den Namen Feldname1
und Feldname2
sehe dann beispielsweise so aus:
Feldname1=Inhalt1&Feldname2=Inhalt2
Die einzelnen Werte der Formularfelder sind also durch ein Gleichheitszeichen (=
) dem entsprechenden Feldnamen zugewiesen, wobei diese Konstrukte jeweils durch ein Und-Zeichen (&
) verbunden werden. Leerzeichen werden durch ein Pluszeichen (+
) ersetzt. Vorkommende Steuerzeichen (z.B.: +
,=
,%
,&
) sowie ASCII-Zeichen werden - eingeleitet durch ein Prozentzeichen (%
) und darauf folgend der Hexadezimalwert des ASCII-Zeichens - hexadezimal kodiert.Diese erzeugten Kodierungszeichen müssen im Script durch Anwenden regulärer Ausdrücke, der
split
-Methode oder ähnlichen Methoden auf den entsprechenden String natürlich noch entfernt werden, damit die einzelnen Feldnamen und -werte in eine brauchbare geordnete Datenstruktur überführt werden können. Das folgende Beispiel zeigt eine Variante, um den mit POST
an das CGI-Skript übertragenden Datenstrom zu entschlüsseln:
read(STDIN, $Formulardaten, $ENV{'CONTENT_LENGTH'});
@Formularfelder = split(/&/, $Formulardaten);
foreach $Feld (@Formularfelder)
{
($Name, $Value) = split(/=/, $Feld);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/<!--(.|n)*-->//g;
if($Name eq "name") { $Username = $Value; }
if($Name eq "password") { $Password = $Value; }
}
$Formulardaten
gespeichert.Mittels der stringspezifischen Funktion
split()
werden die einzelnen Paarungen Formularfeldname und -inhalt aus $Formulardaten
(getrennt durch &
) in das Array @Formularfelder
geschrieben.In einer
foreach
-Schleife werden die einzelnen Elemente der Paarungen Formularfeldname und -inhalt (getrennt durch =
) durch die Funktion split()
in einer Liste gespeichert.Auf die Formularfeldinhalte werden einige reguläre Ausdrücke angewendet, um die Ersetzungsvorgänge der Kodierung und die hexadezimale Kodierung der Steuerzeichen sowie ASCII-Zeichen rückgängig zu machen.
Letztendlich werden die Formularfeldinhalte in einer bedingten Anweisung jeweils einem Skalar zugeordnet
Daten an den Browser ausgeben - Ein erstes Script
Nach Aufruf eines CGI-Skripts auf einem Server durch den Browser erwartet dieser die Rückgabe von Daten bzw. Inhalten durch das CGI-Skript. Diese Datenrückgabe wird in Perl grundsätzlich durch die Funktionprint
ermöglicht:
$Variable = "Inhalt der Variable";
print "Eine Ausgabe an den Browser mit dem Inhalt: $Variable";
print
ausgeben soll, können Zeichenketten sein, welche wiederum Perl-Variablen allerart (hier eine Zeichenkette in der einfachen Variable $Variable
) enthalten dürfen. Nähere Informationen zu Variablen und Zeichenketten erhalten Sie dabei in den entsprechenden Folgeabschnitten.Möchte man größere Mengen HTML-Code an den Browser senden, so wird das ewige Notieren der Funktion
print
nervig. Dafür gibt es eine alternative Variante in Perl. Nach der einleitenden Anweisung print <<"NAME"
; (NAME
ist dabei der so genannte Endbegrenzer, ein frei gewählter Name) kann man HTML-Code auch in Verbindung mit Perl-Variablen notieren, ohne ihn jeweils extra mit der print
Funktion zu verknüpfen. Dieser Codeblock, dessen Inhalt so ausgegeben wird, wie er notiert ist, muss jedoch anschließend durch die Angabe des gleichen/gleich geschriebenen Endbegrenzers (NAME
) abgeschlossen werden, wobei dieser allein in einer Zeile stehen muss:
$text = "auszugebender Text";
print <<"HTMLCODE";
<b>Fett geschriebener Text</b>
$text <br>
HTMLCODE
HTTP-Header ausgeben
Da die für die Ausgabe an den Browser bestimmten Daten über das HTTP-Protokoll zurückgeschickt werden, muss zunächst die Übergabe einer "Einleitung" der Inhalte an den Browser erfolgen. Diese Einleitung, der so genannte HTTP-Header, klassifiziert im Prinzip die nachfolgenden Daten, welche das CGI-Skript ausgeben wird. Dadurch wird es dem Browser erst ermöglicht, die vom CGI-Skript zurückgegebenen Daten dem Clienten gegenüber korrekt darzustellen. Um diesen Sachverhalt zu erklären, wird in Referenzen gern das Beispiel eines einfachen "Hallo Welt"-Skripts angeführt:#!/usr/bin/perl
print "Content-type: text/htmlnn";
#HTTP-Header für nachfolgende HTML-Daten
print "<html>n<head>n";
print "<title>Hallo Welt!</title>n";
print "</head>n<body>n";
print "<b>Hallo Welt</b>n";
print "</body>n</html>";
Die Syntax des HTTP-Headers ist dabei festgelegt: Zunächst wird dieser String durch die Angabe
Content-type:
eingeleitet, was frei übersetzt soviel wie Art des Inhalts bedeutet. Dem folgend wird der Mime-type - dieser Begriff sollte aus HTML bekannt sein - der auszugebenden Daten notiert. Da es sich hierbei üblicherweise um HTML-Daten handelt, wird hier der entsprechende Mime-Type für HTML (text/html
) angegeben. Abschließend muss das Steuerzeichen (siehe Strings) für einen Zeilenumbruch (n
) zweifach notiert werden. Die auf diese Weise zusammengesetzte Zeichenkette - also der HTTP-Header - wird nun mittels der Perl - standardfunktion print
für Ausgaben von Daten an den Browser gesendet. Anschließend wird ein reduziertes HTML-Grundgerüst an den Browser zur Ausgabe übergeben. Der darin enthaltene Text Hallo Welt erscheint schließlich in Fettschrift auf dem Bildschirm des Clients. Die wohl einfachste aller HTML-Ausgaben ist erfolgt.
Tokens
Hinter dem Begriff Tokens (Marke, Zeichen) verbergen sich in Perl Gebilde spezieller Syntax, welche zur Markierung (daher der Begriff Token) logischer Passagen dienen. Sie bestehen aus einem Wort in Großbuchstaben, welches links und rechts von jeweils zwei Unterstrichen (_
) umgeben ist. Folgende Tokens existieren:
__DATA__ oder __END__
#logisches Ende des Codes eines Moduls/Scripts
__FILE__
#Dateiname des ausgeführten Scripts
__LINE__
#Zeilennummer der aktuellen Zeile
__PACKAGE__
#Name d. aktuellen Packages (Namensraum, perlspezifisch)
__DATA__
und __END__
stellen das logische Ende des Moduls oder Scripts dar, was nicht heißt, dass dahinter kein Text mehr notiert werden darf. Ganz im Gegenteil: In Modulen zum Beispiel leiten sie oft den dokumentarischen Teil des Moduls, welcher dem Programmierer Informationen zu Autor, verwendeten Funktionen usw. bereitstellt, ein. Des Weiteren kann hinter diesen beiden Tokens Perl-Code folgen, dessen Kompilierung vor dem Ausführen des Scripts nicht zwingend erforderlich ist. Funktionen oder Methoden, in Perl Subroutinen genannt, können also ebenfalls an dieser Stelle notiert werden.
Du arbeitest in einer Agentur oder als Freelancer?
Dann wirf doch mal einen Blick auf unsere Software FeatValue.
Weiterlesen: ⯈ Reguläre Ausdrücke
Über uns

Wir entwickeln Webanwendungen mit viel Leidenschaft. Unser Wissen geben wir dabei gerne weiter. Mehr über a coding project