Python - CGI-Programmierung: Ein Leitfaden für Anfänger

Hallo dort, zukünftige Python-Zauberer! Ich bin begeistert, Ihr Führer auf dieser spannenden Reise in die Welt der CGI-Programmierung mit Python zu sein. Als jemand, der seit Jahren Informatik lehrt, kann ich Ihnen sagen, dass CGI wie die geheime Sauce ist, die Ihre Webanwendungen zum Leben erweckt. Also, zögen wir die Ärmel hoch und tauchen wir ein!

Python - CGI Programming

Was ist CGI?

CGI steht für Common Gateway Interface. Ich weiß, das klingt wie ein langer Atemzug, aber denken Sie daran, es ist ein Übersetzer zwischen Ihrem Webserver und Ihren Python-Skripten. Es ist wie ein freundlicher Dolmetscher, der Ihrem Server und Ihrem Code eine nahtlose Kommunikation ermöglicht.

CGI ermöglicht es uns, dynamische Webseiten zu erstellen, die auf Benutzereingaben reagieren. Stellen Sie sich eine Webseite vor, die Sie nach Namen grüßt oder personalisierte Inhalte anzeigt - das ist die Magie von CGI am Werk!

Web-Browsing

Bevor wir in die Details der CGI einsteigen, schauen wir uns schnell, wie das Web-Browsing funktioniert. Wenn Sie eine URL in Ihren Browser eingeben, passiert Folgendes:

  1. Ihr Browser sendet eine Anfrage an den Webserver.
  2. Der Webserver verarbeitet die Anfrage.
  3. Der Server sendet eine Antwort zurück, meist in Form einer HTML-Seite.
  4. Ihr Browser rendert diese HTML, zeigt also die Webseite an, die Sie sehen.

CGI kommt ins Spiel, wenn wir in Schritt 3 dynamische Inhalte generieren möchten.

CGI-Architekturdiagramm

Hier ist ein einfaches Diagramm, um zu visualisieren, wie CGI in die Webarchitektur passt:

+-------------+    HTTP-Anfrage    +-------------+
|   Browser   | -----------------> |  Webserver  |
|             | <----------------- |             |
+-------------+    HTTP-Antwort    +-------------+
|
| CGI
v
+-------------+
| CGI-Skript  |
| (Python)    |
+-------------+

Webserver-Unterstützung und Konfiguration

Die meisten Webserver unterstützen CGI, einschließlich Apache und Nginx. Um CGI mit Python zu verwenden, müssen Sie Ihren Server so konfigurieren, dass er Python-Skripte ausführt. Dies beinhaltet in der Regel die Einrichtung eines besonderen Verzeichnisses für CGI-Skripte und das Anzeigen des Servers, dass Dateien in diesem Verzeichnis als ausführbar behandelt werden.

Beispielsweise könnten Sie in Apache folgendes zu Ihrer Konfiguration hinzufügen:

<Directory /var/www/cgi-bin>
Options ExecCGI
AddHandler cgi-script .py
</Directory>

Dies teilt Apache mit, dass .py-Dateien im Verzeichnis /var/www/cgi-bin als CGI-Skripte ausgeführt werden.

Erstes CGI-Programm

Schreiben wir unser erstes CGI-Programm! Wir beginnen mit dem klassischen "Hello, World!"-Beispiel. Erstellen Sie eine Datei namens hello.py in Ihrem CGI-Verzeichnis:

#!/usr/bin/env python3
print("Content-Type: text/html")
print()
print("<html>")
print("<head>")
print("<title>Hello World - Erstes CGI-Programm</title>")
print("</head>")
print("<body>")
print("<h2>Hello World! Dies ist mein erstes CGI-Programm</h2>")
print("</body>")
print("</html>")

Lassen Sie uns das aufbrechen:

  1. Die erste Zeile weist den Server an, Python zu verwenden, um dieses Skript auszuführen.
  2. Content-Type: text/html ist ein HTTP-Header, der dem Browser mitteilt, dass wir HTML senden.
  3. Die leere print() trennt die Header vom Körper der Antwort.
  4. Der Rest ist einfach HTML, das wir dynamisch generieren.

Wenn Sie dieses Skript über Ihren Webbrowser zugreifen, sollten Sie eine Seite sehen, die "Hello World! Dies ist mein erstes CGI-Programm" sagt.

HTTP-Header

In der CGI-Programmierung ist es entscheidend, die richtigen HTTP-Header vor Ihrem Inhalt zu senden. Der häufigste Header ist Content-Type, der dem Browser mitteilt, welche Art von Daten Sie senden. Hier sind einige Beispiele:

Content Type Beschreibung
text/html HTML-Inhalt
text/plain Einfacher Text
image/jpeg JPEG-Bild
application/json JSON-Daten

Denken Sie immer daran, den entsprechenden Content-Type-Header vor Ihrem Inhalt zu senden!

CGI-Umgebungsvariablen

CGI-Skripte haben Zugriff auf verschiedene Umgebungsvariablen, die Informationen über die Anfrage liefern. Hier ist ein Skript, das einige dieser Variablen anzeigt:

#!/usr/bin/env python3
import os

print("Content-Type: text/html")
print()
print("<html><body>")
print("<h2>Umgebungsvariablen:</h2>")
for param in os.environ.keys():
print(f"<b>%20s</b>: {os.environ[param]}<br>" % (param))
print("</body></html>")

Dieses Skript zeigt Ihnen alle verfügbaren Umgebungsvariablen für Ihr CGI-Skript, einschließlich Dinge wie den Browser-Typ des Benutzers, den Servernamen und mehr.

GET- und POST-Methoden

Es gibt zwei Hauptmethoden, um Daten an ein CGI-Skript zu senden: GET und POST. Lassen Sie uns beide betrachten:

GET-Methode

Die GET-Methode sendet Daten als Teil der URL. Hier ist ein einfaches Beispiel:

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
name = form.getvalue('name', 'Welt')

print("<html><body>")
print(f"<h2>Hello, {name}!</h2>")
print("</body></html>")

Sie können auf dieses Skript mit einer URL wie http://yourserver.com/cgi-bin/hello.py?name=Alice zugreifen, und es wird "Hello, Alice!" sagen.

POST-Methode

Die POST-Methode sendet Daten im Körper der HTTP-Anfrage. Sie wird typischerweise für Formulare verwendet. Hier ist ein Beispiel:

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
name = form.getvalue('name', 'Welt')
email = form.getvalue('email', 'Nicht bereitgestellt')

print("<html><body>")
print(f"<h2>Hello, {name}!</h2>")
print(f"<p>Ihre E-Mail-Adresse ist: {email}</p>")
print("</body></html>")

Dieses Skript könnte mit einem HTML-Formular verwendet werden, das die POST-Methode verwendet.

Verarbeitung verschiedener Formularelemente

CGI kann verschiedene Formularelemente verarbeiten. Lassen Sie uns einige Beispiele ansehen:

Kontrollkästchen

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
hobbies = form.getlist('hobby')

print("<html><body>")
print("<h2>Ihre Hobbys:</h2>")
for hobby in hobbies:
print(f"<p>{hobby}</p>")
print("</body></html>")

Optionsfelder

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
gender = form.getvalue('gender', 'Nicht spezifiziert')

print("<html><body>")
print(f"<h2>Ihr Geschlecht: {gender}</h2>")
print("</body></html>")

Textbereich

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
message = form.getvalue('message', 'Keine Nachricht bereitgestellt')

print("<html><body>")
print("<h2>Ihre Nachricht:</h2>")
print(f"<p>{message}</p>")
print("</body></html>")

Auswahlfeld

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
country = form.getvalue('country', 'Nicht ausgewählt')

print("<html><body>")
print(f"<h2>Ihr Land: {country}</h2>")
print("</body></html>")

Verwendung von Cookies in CGI

Cookies sind eine Möglichkeit, kleine Datenstücke auf der Client-Seite zu speichern. Sie sind nützlich, um Benutzereinstellungen zu merken oder Sitzungsinformationen zu pflegen. So können Sie mit Cookies in CGI arbeiten:

Setzen von Cookies

#!/usr/bin/env python3
import cgi
from http import cookies
import datetime

# Erstellen eines Cookies
c = cookies.SimpleCookie()
c['lastvisit'] = str(datetime.datetime.now())
c['lastvisit']['expires'] = 365 * 24 * 60 * 60  # läuft in einem Jahr ab

print(c)  # Dies druckt den Set-Cookie-Header
print("Content-Type: text/html")
print()

print("<html><body>")
print("<h2>Cookie gesetzt!</h2>")
print("</body></html>")

Abrufen von Cookies

#!/usr/bin/env python3
import os
from http import cookies

print("Content-Type: text/html")
print()

if 'HTTP_COOKIE' in os.environ:
cookie_string = os.environ.get('HTTP_COOKIE')
c = cookies.SimpleCookie()
c.load(cookie_string)
lastvisit = c.get('lastvisit')
if lastvisit:
print(f"<h2>Ihre letzte Besichtigung war: {lastvisit.value}</h2>")
else:
print("<h2>Das ist Ihre erste Besichtigung!</h2>")
else:
print("<h2>Das ist Ihre erste Besichtigung!</h2>")

Datei-Upload-Beispiel

Die Verarbeitung von Datei-Uploads ist etwas komplexer, aber hier ist ein einfaches Beispiel:

#!/usr/bin/env python3
import cgi, os
import cgitb; cgitb.enable()

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()

# Dateinamen hier abrufen.
fileitem = form['filename']

# Testen, ob die Datei hochgeladen wurde
if fileitem.filename:
# Führende Pfadangabe vom Dateinamen entfernen,
# um Directory-Traversal-Angriffe zu vermeiden
fn = os.path.basename(fileitem.filename)
open('/tmp/' + fn, 'wb').write(fileitem.file.read())
message = f'Die Datei "{fn}" wurde erfolgreich hochgeladen'
else:
message = 'Keine Datei wurde hochgeladen'

print(f"""\
<html>
<body>
<p>{message}</p>
</body>
</html>
""")

Wie man einen "Datei-Download"-Dialogfenster aufruft?

Um einen Dateidownload auszulösen, müssen Sie die entsprechenden Header setzen:

#!/usr/bin/env python3
import os

filename = "beispiel.txt"  # Dies wäre Ihr Dateiname
filepath = "/pfad/zur/ihre/datei"  # Dies wäre der Pfad zu Ihrer Datei

print("Content-Type: application/octet-stream")
print(f"Content-Disposition: attachment; filename={filename}")
print()  # Leere Zeile, Ende der Header

# Jetzt den Dateiinhalt senden
with open(os.path.join(filepath, filename), 'rb') as f:
print(f.read())

Dieses Skript setzt den Content-Type auf application/octet-stream, was dem Browser mitteilt, die Datei herunterzuladen, anstatt sie anzuzeigen. Der Content-Disposition-Header schlägt einen Dateinamen für den Download vor.

Und da haben wir es, Leute! Wir haben die Grundlagen der CGI-Programmierung mit Python abgedeckt. Denken Sie daran, Übung macht den Meister, also zögern Sie nicht, mit diesen Beispielen zu experimentieren und Ihre eigenen zu erstellen. Glückliches Coden, und möge Ihr CGI-Skript immer glatt laufen!

Credits: Image by storyset