C++ Web Programmierung: Ein Leitfaden für Anfänger

Hallo dort, aufstrebende Webentwickler! Ich freue mich, diese aufregende Reise in die Welt der C++ Web Programmierung gemeinsam mit euch zu beginnen. Als jemand, der seit über einem Jahrzehnt Informatik lehrt, kann ich euch versichern, dass es zwar am Anfang vielleicht schrecklich erscheinen mag, mit Geduld und Übung werdet ihr in kürzester Zeit dynamische Webanwendungen erstellen können. Also, lasst uns loslegen!

C++ Web Programming

Was ist CGI?

Bevor wir anfangen zu programmieren, lassen uns verstehen, was CGI ist. CGI steht für Common Gateway Interface. Es ist wie ein Übersetzer zwischen deinem Webserver und den Programmen, die dynamische Inhalte generieren. Stell dir CGI als einen freundlichen Mittelsmann vor, der Anfragen von Webnutzern entgegennimmt, diese an deine C++-Programme weiterleitet und dann die Ergebnisse an die Browser der Nutzer zurücksendet.

Web-Browsing

Um CGI zu schätzen, müssen wir verstehen, wie Web-Browsing funktioniert. Wenn du eine URL in deinen Browser eingibst, passiert Folgendes:

  1. Dein Browser sendet eine Anfrage an den Webserver.
  2. Der Webserver verarbeitet diese Anfrage.
  3. Wenn es eine statische Seite ist, sendet der Server sie direkt.
  4. Wenn es dynamische Inhalte sind, kommt CGI ins Spiel.
  5. CGI führt das entsprechende Programm aus (bei uns C++-Programme).
  6. Das Programm generiert die Inhalte.
  7. CGI sendet diese Inhalte zurück an den Server.
  8. Der Server liefert die Inhalte an deinen Browser.

CGI-Architekturdiagramm

Lassen uns diesen Prozess mit einem einfachen Diagramm visualisieren:

[Benutzer-Browser] <--> [Webserver] <--> [CGI] <--> [C++-Programm]

Dieses Diagramm zeigt, wie dein C++-Programm über CGI mit dem Web interagiert.

Konfiguration des Web-Servers

Bevor wir unser erstes CGI-Programm schreiben, müssen wir unseren Webserver konfigurieren. Die meisten Webserver wie Apache oder Nginx haben CGI-Module. Du musst diese aktivieren und einen Ordner für deine CGI-Skripte einrichten. Zum Beispiel könntest du in Apache folgendes zu deiner Konfiguration hinzufügen:

ScriptAlias /cgi-bin/ /var/www/cgi-bin/
<Directory "/var/www/cgi-bin">
AllowOverride None
Options +ExecCGI
Require all granted
</Directory>

Dies weist Apache an, Dateien in /var/www/cgi-bin/ als CGI-Skripte zu behandeln.

Erstes CGI-Programm

Nun schreiben wir unser erstes CGI-Programm in C++. Wir beginnen mit einem einfachen "Hello, World!"-Beispiel:

#include <iostream>
using namespace std;

int main() {
cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n";
cout << "<head>\n";
cout << "<title>Hello World - Erstes CGI-Programm</title>\n";
cout << "</head>\n";
cout << "<body>\n";
cout << "<h2>Hello World! Dies ist mein erstes CGI-Programm</h2>\n";
cout << "</body>\n";
cout << "</html>\n";
return 0;
}

Lassen uns das aufbrechen:

  1. Wir inkludieren die iostream-Bibliothek für Eingabe/Ausgabebetriebe.
  2. Die Content-type-Zeile ist entscheidend - sie teilt dem Browser mit, welche Art von Inhalt er erwarten soll.
  3. Wir geben dann HTML-Code aus, genau wie wir es in einer statischen HTML-Datei tun würden.
  4. Die \n-Zeichen stellen sicher, dass sich die Ausgabe korrekt umbricht.

HTTP-Header

In dem vorherigen Beispiel hast du diese Zeile gesehen:

cout << "Content-type:text/html\r\n\r\n";

Dies ist der HTTP-Header. Er ist entscheidend, um dem Browser mitzuteilen, wie er den folgenden Inhalt interpretieren soll. Es gibt viele Arten von Headern, aber jetzt konzentrieren wir uns auf den Content-type-Header.

CGI-Umgebungsvariablen

CGI bietet Umgebungsvariablen, die dir Informationen über die Anfrage geben. Hier ist ein Programm, das einige davon anzeigt:

#include <iostream>
#include <cstdlib>
using namespace std;

int main() {
cout << "Content-type:text/html\r\n\r\n";
cout << "<html><body>";
cout << "SERVER_NAME: " << getenv("SERVER_NAME") << "<br>";
cout << "REQUEST_METHOD: " << getenv("REQUEST_METHOD") << "<br>";
cout << "QUERY_STRING: " << getenv("QUERY_STRING") << "<br>";
cout << "</body></html>";
return 0;
}

Dieses Programm verwendet getenv(), um vom Webserver gesetzte Umgebungsvariablen abzurufen.

C++ CGI-Bibliothek

Um CGI-Programmierung zu erleichtern, können wir Bibliotheken wie cgicc verwenden. Hier ist, wie du sie vielleicht einsetzen könntest:

#include <iostream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << HTMLDoctype(HTMLDoctype::eStrict) << endl;
cout << html() << head(title("Mein erstes CGI-Programm")) << endl;
cout << body() << h1("Hello, World!") << endl;
cout << body() << html();
return 0;
}

Diese Bibliothek bietet Klassen, die die Generierung von HTML und die Handhabung von Formulardaten erleichtern.

GET- und POST-Methoden

Es gibt zwei Hauptmethoden, um Daten an einen Webserver zu senden: GET und POST.

GET-Methode

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

#include <iostream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << html() << body() << endl;

form_iterator name = cgi.getElement("name");
if(name != cgi.getElements().end()) {
cout << "Hello, " << **name << "!" << endl;
} else {
cout << "Kein Name wurde eingereicht." << endl;
}

cout << body() << html();
return 0;
}

Dieses Programm sucht nach einem "name"-Parameter in der URL (z.B. http://deinserver.com/cgi-bin/program?name=John) und begrüßt den Benutzer.

POST-Methode

Die POST-Methode sendet Daten im Körper der HTTP-Anfrage. Sie ist sicherer und kann größere Datenmengen verarbeiten. Hier ist ein Beispiel:

#include <iostream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << html() << body() << endl;

form_iterator name = cgi.getElement("name");
if(name != cgi.getElements().end()) {
cout << "Hello, " << **name << "!" << endl;
} else {
cout << "Kein Name wurde eingereicht." << endl;
}

cout << body() << html();
return 0;
}

Dieser Code sieht ähnlich wie das GET-Beispiel aus, ist aber für POST-Anfragen konzipiert.

Handhabung von Formulardaten

Nun schauen wir uns an, wie verschiedene Arten von Formulardaten gehandhabt werden:

Checkbox-Daten

form_iterator checkbox = cgi.getElement("mycheckbox");
if(checkbox != cgi.getElements().end() && checkbox->getValue() == "on") {
cout << "Checkbox ist ausgewählt!" << endl;
} else {
cout << "Checkbox ist nicht ausgewählt." << endl;
}

Optionsfeld-Daten

form_iterator radio = cgi.getElement("myradio");
if(radio != cgi.getElements().end()) {
cout << "Gewählte Option: " << **radio << endl;
} else {
cout << "Keine Option gewählt." << endl;
}

Textbereich-Daten

form_iterator textarea = cgi.getElement("mytextarea");
if(textarea != cgi.getElements().end()) {
cout << "Textbereichsinhalt: " << **textarea << endl;
} else {
cout << "Textbereich ist leer." << endl;
}

Dropdown-Box-Daten

form_iterator dropdown = cgi.getElement("mydropdown");
if(dropdown != cgi.getElements().end()) {
cout << "Gewählte Option: " << **dropdown << endl;
} else {
cout << "Keine Option gewählt." << endl;
}

Verwendung von Cookies in CGI

Cookies ermöglichen es dir, kleine Datenstücke auf der Maschine des Clients zu speichern. So kannst du Cookies setzen und abrufen:

Setzen von Cookies

#include <cgicc/HTTPCookie.h>

// ... (andere Includes und Namespace-Deklarationen)

int main() {
Cgicc cgi;
HTTPCookie cookie("user", "John Doe");
cookie.setMaxAge(3600);  // Cookie läuft in 1 Stunde ab

cout << HTTPHTMLHeader().setCookie(cookie) << endl;
// ... restliche HTML-Ausgabe
}

Abrufen von Cookies

const CgiEnvironment& env = cgi.getEnvironment();
const vector<HTTPCookie>& cookies = env.getCookieList();

for(vector<HTTPCookie>::const_iterator i = cookies.begin(); i != cookies.end(); ++i) {
if(i->getName() == "user") {
cout << "Willkommen zurück, " << i->getValue() << "!" << endl;
break;
}
}

Datei-Upload-Beispiel

Schließlich schauen wir uns an, wie man Datei-Uploads handhabt:

#include <iostream>
#include <fstream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << html() << body() << endl;

const_file_iterator file = cgi.getFile("userfile");
if(file != cgi.getFiles().end()) {
ofstream out("/Pfad/zum/Upload/Verzeichnis/" + file->getFilename());
out << file->getData();
cout << "Datei " << file->getFilename() << " erfolgreich hochgeladen." << endl;
} else {
cout << "Keine Datei wurde hochgeladen." << endl;
}

cout << body() << html();
return 0;
}

Dieses Programm speichert einen hochgeladenen Datei in einem angegebenen Verzeichnis auf dem Server.

Und das ist es! Wir haben die Grundlagen der C++ Web Programmierung mit CGI behandelt. Denke daran, dass Übung den Meister macht. Probiere diese Beispiele aus, experimentiere damit und bald wirst du komplexe Webanwendungen mit C++ erstellen können. Viel Erfolg beim Coden!

Methode Beschreibung
GET Sendet Daten als Teil der URL
POST Sendet Daten im Körper der HTTP-Anfrage
getElement() Holt Formulardaten von GET- oder POST-Anfragen
setCookie() Setzt einen Cookie auf der Maschine des Clients
getCookieList() Ruft Cookies von der Maschine des Clients ab
getFile() Handhabt Datei-Uploads in CGI

Credits: Image by storyset