Kontakt aufnehmen

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 standardeingabe STDIN 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 standardfunktion read 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; }
 }

Der Datenstrom wird nach oben beschriebenem Prinzip im Skalar $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 Funktion print ermöglicht:

$Variable = "Inhalt der Variable";
print "Eine Ausgabe an den Browser mit dem Inhalt: $Variable";

Die Daten, welche 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>";

Dieses Beispiel - wie immer durch die Shebang-Zeile eingeleitet - erzeugt zunächst einen HTTP-Header, welcher dem Browser signalisiert, dass Daten in Form von HTML-Code an ihn ausgegeben werden sollen.
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) 

Die Tokens __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

Stefan Wienströer

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

Cookie-Einstellungen

Helfen Sie dabei, uns noch besser zu machen. Wir nutzen Cookies und ähnliche Technologien, um die Website auf Ihre Bedürfnisse anzupassen. Zur Datenschutzerklärung

Auswahl speichern