Python - programowanie CGI

Common Gateway Interface (CGI) to zestaw standardów definiujących sposób wymiany informacji między serwerem WWW a niestandardowym skryptem. Specyfikacje CGI są obecnie utrzymywane przez NCSA.

Co to jest CGI?

  • Common Gateway Interface (CGI) jest standardem dla zewnętrznych programów bram do łączenia się z serwerami informacyjnymi, takimi jak serwery HTTP.

  • Obecna wersja to CGI / 1.1, a CGI / 1.2 jest w trakcie opracowywania.

Przeglądanie sieci

Aby zrozumieć koncepcję CGI, zobaczmy, co się dzieje, gdy klikamy hiperłącze w celu przeglądania określonej strony internetowej lub adresu URL.

  • Twoja przeglądarka kontaktuje się z serwerem HTTP i żąda adresu URL, tj. Nazwy pliku.

  • Serwer sieci Web analizuje adres URL i szuka nazwy pliku. Jeśli znajdzie ten plik, odeśle go z powrotem do przeglądarki, w przeciwnym razie wysyła komunikat o błędzie wskazujący, że zażądałeś niewłaściwego pliku.

  • Przeglądarka internetowa pobiera odpowiedź z serwera WWW i wyświetla otrzymany plik lub komunikat o błędzie.

Możliwe jest jednak skonfigurowanie serwera HTTP tak, aby za każdym razem, gdy zażądano pliku w określonym katalogu, plik ten nie był odsyłany; zamiast tego jest wykonywany jako program i cokolwiek ten program wyprowadza, jest przesyłane z powrotem do przeglądarki do wyświetlenia. Ta funkcja nosi nazwę Common Gateway Interface lub CGI, a programy nazywane są skryptami CGI. Te programy CGI mogą być programami w języku Python, PERL Script, Shell Script, C lub C ++ itp.

Diagram architektury CGI

Obsługa i konfiguracja serwera WWW

Przed przystąpieniem do programowania CGI upewnij się, że serwer WWW obsługuje CGI i jest skonfigurowany do obsługi programów CGI. Wszystkie programy CGI, które mają być wykonywane przez serwer HTTP, są przechowywane we wstępnie skonfigurowanym katalogu. Ten katalog nosi nazwę Katalog CGI i zgodnie z konwencją nosi nazwę / var / www / cgi-bin. Zgodnie z konwencją, pliki CGI mają rozszerzenie.cgi, ale możesz zachować swoje pliki z rozszerzeniem Python .py także.

Domyślnie serwer Linux jest skonfigurowany do uruchamiania tylko skryptów z katalogu cgi-bin w / var / www. Jeśli chcesz określić inny katalog do uruchamiania skryptów CGI, skomentuj następujące wiersze w pliku httpd.conf -

<Directory "/var/www/cgi-bin">
   AllowOverride None
   Options ExecCGI
   Order allow,deny
   Allow from all
</Directory>

<Directory "/var/www/cgi-bin">
Options All
</Directory>

W tym przypadku zakładamy, że masz poprawnie skonfigurowany i działający serwer sieciowy oraz że możesz uruchomić dowolny inny program CGI, taki jak Perl lub Shell itp.

Pierwszy program CGI

Oto prosty link, który jest powiązany ze skryptem CGI o nazwie hello.py . Ten plik jest przechowywany w katalogu / var / www / cgi-bin i ma następującą zawartość. Przed uruchomieniem programu CGI upewnij się, że masz zmianę trybu pliku za pomocąchmod 755 hello.py Polecenie UNIX, aby uczynić plik wykonywalnym.

#!/usr/bin/python

print "Content-type:text/html\r\n\r\n"
print '<html>'
print '<head>'
print '<title>Hello World - First CGI Program</title>'
print '</head>'
print '<body>'
print '<h2>Hello World! This is my first CGI program</h2>'
print '</body>'
print '</html>'

Jeśli klikniesz hello.py, spowoduje to następujący wynik -

Witaj świecie! To jest mój pierwszy program CGI

Ten hello.py skrypt jest prostym skryptem w Pythonie, który zapisuje swoje dane wyjściowe w pliku STDOUT, tj. Screen. Dostępna jest jedna ważna i dodatkowa funkcja, czyli pierwsza linia do wydrukowaniaContent-type:text/html\r\n\r\n. Ta linia jest wysyłana z powrotem do przeglądarki i określa typ zawartości, która ma być wyświetlana na ekranie przeglądarki.

Do tej pory musisz już zrozumieć podstawową koncepcję CGI i możesz pisać wiele skomplikowanych programów CGI w języku Python. Ten skrypt może współdziałać z dowolnym innym systemem zewnętrznym również w celu wymiany informacji, takich jak RDBMS.

Nagłówek HTTP

Linia Content-type:text/html\r\n\r\njest częścią nagłówka HTTP, który jest wysyłany do przeglądarki w celu zrozumienia treści. Cały nagłówek HTTP będzie miał następującą postać -

HTTP Field Name: Field Content

For Example
Content-type: text/html\r\n\r\n

Istnieje kilka innych ważnych nagłówków HTTP, których będziesz często używać w programowaniu CGI.

Sr.No. Nagłówek i opis
1

Content-type:

Ciąg MIME określający format zwracanego pliku. Przykład: Typ treści: tekst / html

2

Expires: Date

Data utraty informacji. Jest używany przez przeglądarkę do decydowania, kiedy strona wymaga odświeżenia. Prawidłowy ciąg daty ma format 01 Jan 1998 12:00:00 GMT.

3

Location: URL

Adres URL, który jest zwracany zamiast żądanego adresu URL. Możesz użyć tego pola, aby przekierować żądanie do dowolnego pliku.

4

Last-modified: Date

Data ostatniej modyfikacji zasobu.

5

Content-length: N

Długość zwracanych danych w bajtach. Przeglądarka używa tej wartości do raportowania szacowanego czasu pobierania pliku.

6

Set-Cookie: String

Ustaw plik cookie przekazany przez ciąg

Zmienne środowiskowe CGI

Wszystkie programy CGI mają dostęp do następujących zmiennych środowiskowych. Te zmienne odgrywają ważną rolę podczas pisania dowolnego programu CGI.

Sr.No. Nazwa i opis zmiennej
1

CONTENT_TYPE

Typ danych treści. Używane, gdy klient wysyła załączoną zawartość do serwera. Na przykład przesyłanie plików.

2

CONTENT_LENGTH

Długość informacji o zapytaniu. Jest dostępny tylko dla żądań POST.

3

HTTP_COOKIE

Zwraca ustawione pliki cookie w postaci pary klucz-wartość.

4

HTTP_USER_AGENT

Pole nagłówka żądania agenta użytkownika zawiera informacje o kliencie użytkownika, który wysłał żądanie. Jest to nazwa przeglądarki internetowej.

5

PATH_INFO

Ścieżka do skryptu CGI.

6

QUERY_STRING

Informacje zakodowane w adresie URL, które są wysyłane z żądaniem metody GET.

7

REMOTE_ADDR

Adres IP zdalnego hosta wysyłającego żądanie. Jest to przydatne do logowania lub do uwierzytelniania.

8

REMOTE_HOST

W pełni kwalifikowana nazwa hosta wysyłającego żądanie. Jeśli ta informacja nie jest dostępna, można użyć REMOTE_ADDR do uzyskania adresu IR.

9

REQUEST_METHOD

Metoda użyta do wysłania żądania. Najpopularniejsze metody to GET i POST.

10

SCRIPT_FILENAME

Pełna ścieżka do skryptu CGI.

11

SCRIPT_NAME

Nazwa skryptu CGI.

12

SERVER_NAME

Nazwa hosta lub adres IP serwera

13

SERVER_SOFTWARE

Nazwa i wersja oprogramowania, na którym działa serwer.

Oto mały program CGI do wyszczególnienia wszystkich zmiennych CGI. Kliknij to łącze, aby zobaczyć wynik Pobierz środowisko

#!/usr/bin/python

import os

print "Content-type: text/html\r\n\r\n";
print "<font size=+1>Environment</font><\br>";
for param in os.environ.keys():
   print "<b>%20s</b>: %s<\br>" % (param, os.environ[param])

Metody GET i POST

Musiałeś spotkać się z wieloma sytuacjami, w których musisz przekazać pewne informacje z przeglądarki na serwer WWW, a ostatecznie do programu CGI. Najczęściej przeglądarka używa dwóch metod przekazywania tych informacji do serwera WWW. Te metody to metoda GET i metoda POST.

Przekazywanie informacji metodą GET

Metoda GET wysyła zakodowane informacje o użytkowniku dołączone do żądania strony. Strona i zakodowane informacje są oddzielone znakiem? znak w następujący sposób -

http://www.test.com/cgi-bin/hello.py?key1=value1&key2=value2

Metoda GET jest domyślną metodą przekazywania informacji z przeglądarki do serwera WWW i tworzy długi ciąg znaków, który pojawia się w polu Lokalizacja: przeglądarki. Nigdy nie używaj metody GET, jeśli masz hasło lub inne poufne informacje do przekazania na serwer. Metoda GET ma ograniczenie rozmiaru: w ciągu żądania można wysłać tylko 1024 znaki. Metoda GET wysyła informacje przy użyciu nagłówka QUERY_STRING i będzie dostępna w programie CGI poprzez zmienną środowiskową QUERY_STRING.

Możesz przekazywać informacje, po prostu łącząc pary klucz i wartość wraz z dowolnym adresem URL lub możesz użyć tagów HTML <FORM>, aby przekazać informacje za pomocą metody GET.

Prosty przykład adresu URL: metoda pobierania

Oto prosty adres URL, który przekazuje dwie wartości do programu hello_get.py przy użyciu metody GET.

/cgi-bin/hello_get.py?first_name=ZARA&last_name=ALI

Poniżej jest hello_get.pyskrypt do obsługi danych wejściowych podawanych przez przeglądarkę internetową. Będziemy używaćcgi moduł, który bardzo ułatwia dostęp do przekazywanych informacji -

#!/usr/bin/python

# Import modules for CGI handling 
import cgi, cgitb 

# Create instance of FieldStorage 
form = cgi.FieldStorage() 

# Get data from fields
first_name = form.getvalue('first_name')
last_name  = form.getvalue('last_name')

print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Hello - Second CGI Program</title>"
print "</head>"
print "<body>"
print "<h2>Hello %s %s</h2>" % (first_name, last_name)
print "</body>"
print "</html>"

Dałoby to następujący wynik -

Witam ZARA ALI

Prosty przykład FORMULARZA: GET Method

W tym przykładzie dwie wartości są przekazywane za pomocą formularza HTML i przycisku przesyłania. Używamy tego samego skryptu CGI hello_get.py do obsługi tego wejścia.

<form action = "/cgi-bin/hello_get.py" method = "get">
First Name: <input type = "text" name = "first_name">  <br />

Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />
</form>

Oto rzeczywiste dane wyjściowe powyższego formularza, wprowadź imię i nazwisko, a następnie kliknij przycisk przesyłania, aby zobaczyć wynik.

Przekazywanie informacji metodą POST

Generalnie bardziej niezawodną metodą przekazywania informacji do programu CGI jest metoda POST. Spowoduje to pakowanie informacji dokładnie w taki sam sposób, jak metody GET, ale zamiast wysyłać je jako ciąg tekstowy po znaku? w adresie URL wysyła go jako oddzielną wiadomość. Ta wiadomość pojawia się w skrypcie CGI w postaci standardowego wejścia.

Poniżej znajduje się ten sam skrypt hello_get.py, który obsługuje metodę GET i POST.

#!/usr/bin/python

# Import modules for CGI handling 
import cgi, cgitb 

# Create instance of FieldStorage 
form = cgi.FieldStorage() 

# Get data from fields
first_name = form.getvalue('first_name')
last_name  = form.getvalue('last_name')

print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Hello - Second CGI Program</title>"
print "</head>"
print "<body>"
print "<h2>Hello %s %s</h2>" % (first_name, last_name)
print "</body>"
print "</html>"

Weźmy ponownie ten sam przykład co powyżej, który przekazuje dwie wartości za pomocą FORMULARZA HTML i przycisku przesyłania. Używamy tego samego skryptu CGI hello_get.py do obsługi tego wejścia.

<form action = "/cgi-bin/hello_get.py" method = "post">
First Name: <input type = "text" name = "first_name"><br />
Last Name: <input type = "text" name = "last_name" />

<input type = "submit" value = "Submit" />
</form>

Oto rzeczywisty wynik powyższego formularza. Wpisz Imię i Nazwisko, a następnie kliknij przycisk Prześlij, aby zobaczyć wynik.

Przekazywanie danych pola wyboru do programu CGI

Pola wyboru są używane, gdy wymagane jest wybranie więcej niż jednej opcji.

Oto przykładowy kod HTML formularza z dwoma polami wyboru -

<form action = "/cgi-bin/checkbox.cgi" method = "POST" target = "_blank">
<input type = "checkbox" name = "maths" value = "on" /> Maths
<input type = "checkbox" name = "physics" value = "on" /> Physics
<input type = "submit" value = "Select Subject" />
</form>

Wynikiem tego kodu jest następująca postać -

Poniżej znajduje się skrypt checkbox.cgi do obsługi danych wejściowych podawanych przez przeglądarkę internetową dla przycisku wyboru.

#!/usr/bin/python

# Import modules for CGI handling 
import cgi, cgitb 

# Create instance of FieldStorage 
form = cgi.FieldStorage() 

# Get data from fields
if form.getvalue('maths'):
   math_flag = "ON"
else:
   math_flag = "OFF"

if form.getvalue('physics'):
   physics_flag = "ON"
else:
   physics_flag = "OFF"

print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Checkbox - Third CGI Program</title>"
print "</head>"
print "<body>"
print "<h2> CheckBox Maths is : %s</h2>" % math_flag
print "<h2> CheckBox Physics is : %s</h2>" % physics_flag
print "</body>"
print "</html>"

Przekazywanie danych przycisku radiowego do programu CGI

Przyciski radiowe są używane, gdy wymagana jest tylko jedna opcja.

Oto przykład kodu HTML dla formularza z dwoma przyciskami opcji -

<form action = "/cgi-bin/radiobutton.py" method = "post" target = "_blank">
<input type = "radio" name = "subject" value = "maths" /> Maths
<input type = "radio" name = "subject" value = "physics" /> Physics
<input type = "submit" value = "Select Subject" />
</form>

Wynikiem tego kodu jest następująca postać -

Poniżej znajduje się skrypt radiobutton.py do obsługi danych wejściowych podanych przez przeglądarkę internetową dla przycisku opcji -

#!/usr/bin/python

# Import modules for CGI handling 
import cgi, cgitb 

# Create instance of FieldStorage 
form = cgi.FieldStorage() 

# Get data from fields
if form.getvalue('subject'):
   subject = form.getvalue('subject')
else:
   subject = "Not set"

print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Radio - Fourth CGI Program</title>"
print "</head>"
print "<body>"
print "<h2> Selected Subject is %s</h2>" % subject
print "</body>"
print "</html>"

Przekazywanie danych obszaru tekstowego do programu CGI

Element TEXTAREA jest używany, gdy tekst wielowierszowy ma zostać przesłany do programu CGI.

Oto przykładowy kod HTML dla formularza z polem TEXTAREA -

<form action = "/cgi-bin/textarea.py" method = "post" target = "_blank">
<textarea name = "textcontent" cols = "40" rows = "4">
Type your text here...
</textarea>
<input type = "submit" value = "Submit" />
</form>

Wynikiem tego kodu jest następująca postać -

Poniżej znajduje się skrypt textarea.cgi do obsługi danych wejściowych podawanych przez przeglądarkę internetową -

#!/usr/bin/python

# Import modules for CGI handling 
import cgi, cgitb 

# Create instance of FieldStorage 
form = cgi.FieldStorage() 

# Get data from fields
if form.getvalue('textcontent'):
   text_content = form.getvalue('textcontent')
else:
   text_content = "Not entered"

print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>";
print "<title>Text Area - Fifth CGI Program</title>"
print "</head>"
print "<body>"
print "<h2> Entered Text Content is %s</h2>" % text_content
print "</body>"

Przekazywanie danych z rozwijanej skrzynki do programu CGI

Drop Down Box jest używany, gdy mamy wiele dostępnych opcji, ale tylko jedna lub dwie zostaną wybrane.

Oto przykładowy kod HTML dla formularza z jednym rozwijanym oknem -

<form action = "/cgi-bin/dropdown.py" method = "post" target = "_blank">
<select name = "dropdown">
<option value = "Maths" selected>Maths</option>
<option value = "Physics">Physics</option>
</select>
<input type = "submit" value = "Submit"/>
</form>

Wynikiem tego kodu jest następująca postać -

Poniżej znajduje się skrypt dropdown.py obsługujący dane wejściowe podawane przez przeglądarkę internetową.

#!/usr/bin/python

# Import modules for CGI handling 
import cgi, cgitb 

# Create instance of FieldStorage 
form = cgi.FieldStorage() 

# Get data from fields
if form.getvalue('dropdown'):
   subject = form.getvalue('dropdown')
else:
   subject = "Not entered"

print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Dropdown Box - Sixth CGI Program</title>"
print "</head>"
print "<body>"
print "<h2> Selected Subject is %s</h2>" % subject
print "</body>"
print "</html>"

Korzystanie z plików cookie w CGI

Protokół HTTP jest protokołem bezstanowym. W przypadku komercyjnej witryny internetowej wymagane jest przechowywanie informacji o sesjach między różnymi stronami. Na przykład jedna rejestracja użytkownika kończy się po wypełnieniu wielu stron. Jak zachować informacje o sesji użytkownika na wszystkich stronach internetowych?

W wielu sytuacjach używanie plików cookie jest najskuteczniejszą metodą zapamiętywania i śledzenia preferencji, zakupów, prowizji i innych informacji wymaganych dla lepszych wrażeń odwiedzających lub statystyk witryny.

Jak to działa?

Twój serwer przesyła pewne dane do przeglądarki odwiedzającego w formie pliku cookie. Przeglądarka może zaakceptować plik cookie. Jeśli tak, jest przechowywany jako zwykły zapis tekstowy na dysku twardym gościa. Teraz, gdy użytkownik przejdzie na inną stronę w Twojej witrynie, plik cookie jest dostępny do pobrania. Po odzyskaniu serwer wie / pamięta, co zostało zapisane.

Pliki cookie to zapis danych w postaci zwykłego tekstu składający się z 5 pól o zmiennej długości -

  • Expires- data wygaśnięcia pliku cookie. Jeśli pole jest puste, plik cookie wygaśnie, gdy odwiedzający zamknie przeglądarkę.

  • Domain - nazwa domeny Twojej witryny.

  • Path- Ścieżka do katalogu lub strony internetowej, która ustawia plik cookie. To może być puste, jeśli chcesz pobrać plik cookie z dowolnego katalogu lub strony.

  • Secure- Jeśli to pole zawiera słowo „bezpieczne”, plik cookie można pobrać tylko z bezpiecznego serwera. Jeśli to pole jest puste, takie ograniczenie nie istnieje.

  • Name=Value - Pliki cookie są ustawiane i pobierane w postaci par klucza i wartości.

Konfiguracja plików cookie

Wysyłanie plików cookie do przeglądarki jest bardzo łatwe. Te pliki cookie są wysyłane wraz z nagłówkiem HTTP przed do pola typu zawartości. Zakładając, że chcesz ustawić identyfikator użytkownika i hasło jako pliki cookie. Ustawienie plików cookie odbywa się w następujący sposób -

#!/usr/bin/python

print "Set-Cookie:UserID = XYZ;\r\n"
print "Set-Cookie:Password = XYZ123;\r\n"
print "Set-Cookie:Expires = Tuesday, 31-Dec-2007 23:12:40 GMT";\r\n"
print "Set-Cookie:Domain = www.tutorialspoint.com;\r\n"
print "Set-Cookie:Path = /perl;\n"
print "Content-type:text/html\r\n\r\n"
...........Rest of the HTML Content....

Na podstawie tego przykładu musisz wiedzieć, jak ustawić pliki cookie. UżywamySet-Cookie Nagłówek HTTP do ustawiania plików cookie.

Opcjonalne jest ustawienie atrybutów plików cookie, takich jak Wygasa, Domena i Ścieżka. Warto zauważyć, że pliki cookie są ustawiane przed wysłaniem magicznej linii"Content-type:text/html\r\n\r\n.

Pobieranie plików cookie

Pobranie wszystkich ustawionych plików cookie jest bardzo łatwe. Pliki cookie są przechowywane w zmiennej środowiskowej CGI HTTP_COOKIE i będą miały następującą postać -

key1 = value1;key2 = value2;key3 = value3....

Oto przykład, jak odzyskać pliki cookie.

#!/usr/bin/python

# Import modules for CGI handling 
from os import environ
import cgi, cgitb

if environ.has_key('HTTP_COOKIE'):
   for cookie in map(strip, split(environ['HTTP_COOKIE'], ';')):
      (key, value ) = split(cookie, '=');
      if key == "UserID":
         user_id = value

      if key == "Password":
         password = value

print "User ID  = %s" % user_id
print "Password = %s" % password

Daje to następujący wynik dla plików cookie ustawionych przez powyższy skrypt -

User ID = XYZ
Password = XYZ123

Przykład przesyłania plików

Aby przesłać plik, formularz HTML musi mieć atrybut enctype ustawiony na multipart/form-data. Znacznik wejściowy z typem pliku tworzy przycisk „Przeglądaj”.

<html>
<body>
   <form enctype = "multipart/form-data" 
                     action = "save_file.py" method = "post">
   <p>File: <input type = "file" name = "filename" /></p>
   <p><input type = "submit" value = "Upload" /></p>
   </form>
</body>
</html>

Wynikiem tego kodu jest następująca postać -

Powyższy przykład został celowo wyłączony, aby zapisać osoby przesyłające plik na nasz serwer, ale możesz wypróbować powyższy kod na swoim serwerze.

Oto skrypt save_file.py do obsługi przesyłania plików -

#!/usr/bin/python

import cgi, os
import cgitb; cgitb.enable()

form = cgi.FieldStorage()

# Get filename here.
fileitem = form['filename']

# Test if the file was uploaded
if fileitem.filename:
   # strip leading path from file name to avoid 
   # directory traversal attacks
   fn = os.path.basename(fileitem.filename)
   open('/tmp/' + fn, 'wb').write(fileitem.file.read())

   message = 'The file "' + fn + '" was uploaded successfully'
   
else:
   message = 'No file was uploaded'
   
print """\
Content-Type: text/html\n
<html>
<body>
   <p>%s</p>
</body>
</html>
""" % (message,)

Jeśli uruchomisz powyższy skrypt w systemie Unix / Linux, musisz zadbać o zastąpienie separatora plików w następujący sposób, w przeciwnym razie na komputerze z systemem Windows powyżej instrukcja open () powinna działać dobrze.

fn = os.path.basename(fileitem.filename.replace("\\", "/" ))

Jak wywołać okno dialogowe „Pobieranie pliku”?

Czasami pożądane jest udostępnienie opcji, w której użytkownik może kliknąć łącze, a zamiast wyświetlania rzeczywistej zawartości wyświetli się okno dialogowe „Pobieranie pliku”. Jest to bardzo łatwe i można to osiągnąć za pomocą nagłówka HTTP. Ten nagłówek HTTP różni się od nagłówka wspomnianego w poprzedniej sekcji.

Na przykład, jeśli chcesz utworzyć plik FileName plik do pobrania z podanego linku, to jego składnia jest następująca -

#!/usr/bin/python

# HTTP Header
print "Content-Type:application/octet-stream; name = \"FileName\"\r\n";
print "Content-Disposition: attachment; filename = \"FileName\"\r\n\n";

# Actual File Content will go here.
fo = open("foo.txt", "rb")

str = fo.read();
print str

# Close opend file
fo.close()

Mam nadzieję, że podobał Ci się ten samouczek. Jeśli tak, prześlij mi swoją opinię na adres: Skontaktuj się z nami