CGI 2

Formuláře

CPG programy jsou často určeny pro zpracování dat odeslaných prohlížečem (formulářem). Vracejí prohlížeči informace na základě těchto dat.

HTML formuláře slouží k získání dat prohlížečem od uživatele. V tomto článku ukáži jak se takový jednoduchý formulář vytvoří. Je to malá odbočka do strukturovaného jazyka HTML.

Formulář je uvozen párovou značkou <form>, která by měla mít minimálně dva atributy: action a method.

Atribut action určuje CGI program, kterému budou předány informace z formuláře ke spracování. Atribut method určuje, jakým způsobem budou data serveru odeslána.

Možnosti způsobu odeslání (method) jsou dvě: GET a POST. Metoda GET uloží data z formuláře do QUERY_STRINGu (vysvětlím později), metoda POST předá data z formuláře programu jako standardní vstup. (Metoda POST se hodí především pro přenášení velkého oběmu dat.) Prázdný formulář tedy může vypadat nějak takto:

<form action="http://localhost/cgi-bin/program.cgi" method="GET">
</form>

Formulář také musí mít nějaké INPUTy pro možnost vložení textu a tlačítko SUBMIT pro odeslání formuláře. INPUTy musí mít jméno (NAME), aby CGI skript rozeznal, co jste do kterého INPUTu zapsali a typ (TYPE) (TEXT pro text, PASSWORD pro heslo atp.)

<form action="http://localhost/cgi-bin/program.cgi" method="get">
    Jmeno:<br /><input type="text" name="jmeno" /><br />
    Prijmeni:<br /><input type="text" name="prijmeni" /><br />
    <input type="submit" />
</form>

Takovýto formulář musí samozřejmě být součástí HTML stránky. Celá stránka vypadá takto:

<html>
    <head>
    </head>
    <body>
        <form action="http://localhost/cgi-bin/program.cgi" method="get">
            Jmeno:<br /><input type="text" name="jmeno" /><br />
            Prijmeni:<br /><input type="text" name="prijmeni" /><br />
            <input type="submit" />
        </form>
    </body>
</html>

A takto vypadá výsledek:

Jmeno:

Prijmeni:

Vytvořte si HTML stránku s tímto formulářem. Uvidíte vstupní pole pro text a tlačítko submit. Po jeho stisknutí se odešlou data CGI programu program.cgi, který jste vytvořili v minulé kapitole.

QUERY_STRING

Data, která jste do formuláře zapsali se uložili do proměnné prostředí s názvem QUERY_STRING. Pokud voláte CGI program program.cgi přímo přes jeho URL adresu http://localhost/cgi-bin/program.cgi, je QUERY_STRING prázdný.

Pokud použijete formulář a zapíšete za jméno Pavel a příjmení Vomáčka, bude QUERY_STRING obsahovat toto:

jmeno=Pavel&prijmeni=Vom%C3%A1%C4%8Dka

Tedy jméno prvku formuláře (NAME), rovnítko a hodnotu prvku formuláře. Jednotlivé prvky formuláře QUERY_STRING odděluje znak &. Všimněte si, že národní znaky (jako á a č) jsou zakódovány řetězci začínajícími procentem.

Budete-li chtít v cgi programu vytisknout QUERY_STRING, můžete to udělat takto:

#! /usr/bin/env python3
#

print('Content-type: text/html\n')   # '\n' vytvori novy (prazdny) radek
                                     # pouziva se pro ukonceni hlavicky

print('<html><body>')
import os
if 'QUERY_STRING' in os.environ:
       print(os.environ['QUERY_STRING'])

print('</body></html>')

Všimněte si, že pokud použijete ve formuláři pro odeslání dat metodu GET, URL adresa, na kterou se Váš prohlížeč pokouší přihlásit, je ve tvaru:
http://localhost/cgi-bin/program.cgi?jmeno=Pavel&prijmeni=Vom%C3%A1%C4%8Dka
Tedy: URL CGI programu, otazník a QUERY_STRING. Hádejte co se stane, když do adresy svého prohlížeče zadáte:
http://localhost/cgi-bin/program.cgi?jmeno=Thomas+Alva&prijmeni=Edison.

Modul cgi

Jistě už přemýšlíte, jak z QUERY_STRINGu získat potřebné informace. Začíná se Vám rosit čelo při představě, že byste měli napsat funkci, která by QUERY_STRING procházela znak po znaku a zjišťovala jména prvků formuláře a příslušné hodnoty. Nemusíte se bát, taková funkce již existuje. A ne jedna.

cgi.parse_qs()

První zajímavá funkce modulu cgi se jmenuje parse_qs(). Jejím atributem je QUERY_STRING a návratovou hodnotou je slovník, jehož klíči jsou jména prvků formuláře a hodnoty příslušné hodnoty formuláře jako seznam. Funkci parse_qs() můžete vyzkoušet i v interaktivním režimu.

>>> import cgi
>>> cgi.parse_qs('jmeno=Pavel&prijmeni=Vom%E\1%E8ka')
{'prijmeni': ['Vom%E\x01\xe8ka'], 'jmeno': ['Pavel']}
>>> qs = cgi.parse_qs('jmeno=Pavel&prijmeni=Vom%E\1%E8ka')
>>> print(qs['prijmeni'])
['Vom%E\x01\xe8ka']
>>> type(qs['prijmeni'])
<type 'list'>

V CGI programu byste využili funkci parse_qs takto:

#! /usr/bin/env python
#

print('Content-type: text/html; Charset="UTF-8"\n')

print '<html><body>'
import os, cgi

QS = os.environ['QUERY_STRING']
qs = cgi.parse_qs(QS)
print('QS=' + str(QS) + '<br />')
print('qs=' + str(qs))
print('</body></html>')

Pokud do formuláře zadáte do textového pole jmeno Thomas Alva a do pole prijmeni Edison, potom se vám vrátí řádky:

QS=jmeno=Thomas+Alva&prijmeni=Edison
qs={'prijmeni': ['Edison'], 'jmeno': ['Thomas Alva']}

cgi.FieldStorage()

Funkce parse_qs() má několik nevýhod. Jednak nedekóduje národní znaky (nechává je ve tvaru %kód znaku a druhak pracuje jen s QUERY_STRINGem.

Pokud však formulář použije metodu POST, data jsou předána CGI programu prostřednictvím standardního vstupu, nikoliv QUERY_STRINGu. Tyto problémy vyřeší funkce FieldStorage().

Návratovou hodnotou funkce FieldStorage() je objekt FieldStorage jehož prvky jsou objekty typu MiniFieldStorage.

Upravte předchozí CGI program následovně:

#! /usr/bin/env python
#

print('Content-type: text/html; Charset="UTF-8"\n')
print('<html><body>')

import os, cgi

QS = os.environ['QUERY_STRING']
qs = cgi.parse_qs(QS)
print('QS=' + str(QS) + '<br />')
print('qs=' + str(qs) + '<br />')

f = cgi.FieldStorage()
if 'jmeno' in f and 'prijmeni' in f:
        print(f['jmeno'].value + " "+f['prijmeni'].value)
else:
        print('Musite zadat jmeno a prijmeni')

print('</body></html>')

Pokud do formuláře zadáte do textového pole za jméno text Mléčná a za příjmení text Výživa, uvidíte následující výstup:

QS=jmeno=Ml%C3%A9%C4%8Dn%C3%A1&prijmeni=V%C3%BD%C5%BEiva
qs={'prijmeni': ['V\xc3\xbd\xc5\xbeiva'], 'jmeno': ['Ml\xc3\xa9\xc4\x8dn\xc3\xa1']}
Mléčná Výživa

Změníte-li metodu formuláře z metody GET na POST, uvidíte následující:

QS=
qs={}

Mléčná Výživa

Snad už není co dodávat.
THE END.

Dodatek: Pokud to myslíte s psaním webů v Pythonu vážně, podívejte se po nějakém frameworku. (Například Django je hodně populární a konečně podporuje i Python 3! (od verze 1.5)).
Komentář Hlášení chyby
Created: 11.9.2005
Last updated: 2.9.2015