4. Formos ir CGI

  1. HTML elementai formų kūrime
  2. Duomenų siuntimas serveriui
  3. Savikontrolės klausimai

Kaip jau minėjome įvade, formos dažniausiai naudojamos dviem tikslais: duomenų gavimui ir interaktyviam bendravimui.

Pagrindinė formų nauda yra ta, kad jos gali būti naudojamos įvairių sąsajų (gateways) išoriniam interfeisui sudaryti. Toks interfeisas yra prieinamas  (suprantamas) visiems Web klientams, nepriklausomai nuo sistemos ypatybių. Tačiau kita vertus, formos turi keletą trūkumų:

 

4.1. HTML elementai formų kūrime

Formos susideda iš dviejų dalių: HTML kodo ir CGI programos. HTML žymės (tags) sukuria formos dizainą, tuo metu kai CGI programa dekoduoja formos turinio informaciją. Prieš pradėdami nagrinėti informacijos apdorojimą, pažiūrėkime, kaip formos yra kuriamos.

Štai formos elementų panaudojimo pavyzdys 4.1, juo remsimės nagrinėdami pavyzdžius tolesniuose poskyriuose.

   

4.1.1. "FORM" žymė

Paprastai formos prasideda maždaug taip:

<FORM ACTION="pvz41.pl" METHOD="POST">

Forma prasideda žyme <FORM>. Web dokumentas gali turėti įvairių formų, tačiau viena forma negali būti kitos formos dalis.

Svarbiausi <FORM> žymės atributai yra ACTION ir METHOD. ACTION  atributas nurodo URL programos, kuri apdoros formos informaciją. Nėra apribojimo naudoti tik savo serveryje esančias CGI programas. Galima nurodyti bet kur tinkle esančių programų URL.

METHOD atributas nurodo, kaip serveris persiunčia formos informaciją programai. POST metodas persiunčia duomenis naudodamas standartinį įvedimo įrenginį (STDIN), o GET metodas - naudodamas sisteminius kintamuosius. Jei METHOD atributas nėra nurodytas, pagal nutylėjimą naudojamas GET metodas. Kiekvienas šių metodų turi savus trūkumus ir privalumus, kuriuos detaliau aptarsime šiame skyrelyje  truputi vėliau.

Be anksčiau minėtų atributų, gali būti nurodytas dar vienas - ENCTYPE. Jis nurodo POST metodu gautų duomenų MIME tipą (arba dekodavimo schemą). Jis gali turėti dvi reikšmes: application/x-www-form-urlencoded arba multipart/form-data. Jei nei viena jų nėra nurodyta, pagal nutylėjimą paimama application/x-www-form-urlencoded reikšmė.

 

4.1.2. Tekstiniai ir slaptažodžio laukai

Dauguma formos elementų yra kuriami naudojant <INPUT> žymę. Šios žymės atributas TYPE apibrėžia, kokio tipo įvedimas bus atliekamas. Galimi tokie elementų tipai: tekstiniai ir slaptažodžio laukai, "radio butons", ir "checkboxes". Sekančios eilutės yra paprasto teksto įvedimo pavyzdys.

Name: <INPUT TYPE="text" NAME="user" SIZE=40><BR>
Age: <INPUT TYPE="text" NAME="age" SIZE=3 MAXLENGTH=3><BR>
Password: <INPUT TYPE="password" NAME="pass" SIZE=10><BR>

Šiuo atveju sukuriami du tekstiniai ir vienas slaptažodžio laukas, panaudojant "text" ir "password" argumentus atitinkamai. Slaptažodžio laukas yra toks pat, kaip ir tekstinis, tik vietoj įvedamų simbolių mes matome žvaigždutes '*'. Praleidus TYPE atributą, pagal nutylėjimą sukuriamas tekstinis laukas.

NAME atributas apibrėžia įvesto elemento vardą. Jis neatvaizduojamas ekrane, bet naudojamas perduodant informaciją CGI programai. Pavyzdžiui, jei lauke "user" įvesime "andy", tai naršyklė supras taip: user=andy. Vėliau CGI programa gali atsirinkti šią informaciją.

Neprivalomas atributas VALUE gali būti naudojamas, nurodant lauko reikšmę pagal nutylėjimą. Ši reikšmė gali būti vartotojo pakeista.

Kiti du neprivalomi atributai yra SIZE ir MAXLENGTH. SIZE nurodo fizinį įvedimo elemento (lauko) dydį. Jeigu įvedama informacija yra didesnė, tai laukas persistums (prasisuks). Lauko dydis pagal nutylėjimą yra 20 simbolių. MAXLENGTH nurodo maksimalų simbolių skaičių, kuriuos peržiūros programa nuskaitys. Pagal nutylėjimą neužduodami jokie apribojimai.

Dar vienas tekstinio lauko tipas yra "paslėptas" laukas. Jis leidžia patalpinti informaciją į formą. Vartotojas šios informacijos nematys. Pavyzdžiui:

<INPUT TYPE="hidden" NAME="publisher" VALUE="ORA">

Paslėptas laukas dažniausiai naudojamas perduoti informacijai iš vienos formos kitai.

 

4.1.3. Patvirtinimo ir atsisakymo mygtukai

Yra dar du <INPUT> žymės tipai: submit ir reset.

<INPUT TYPE="submit" VALUE="Submit the form">
<INPUT TYPE="reset" VALUE="Clear all fields">

Beveik visos formos turi patvirtinimo (submit) ir atsisakymo (reset) mygtukus. Patvirtinimo mygtukas siunčia visą formos informacijos turinį CGI programai, nurodytai ACTION atributu. Be šio mygtuko forma būtų nenaudinga, nes jos informacija nepasiektų CGI programos.

Pagal nutylėjimą šiems mygtukams priskiriami "Submit" ir "Reset" vardai. Juos galima pervadinti naudojant VALUE atributą.

Forma gali turėti kelis patvirtinimo mygtukus.

<INPUT TYPE="submit" VALUE="Option 1">
<INPUT TYPE="submit" VALUE="Option 2">

Jeigu nuspausime mygtuką "Option 1", CGI programa gaus tokius duomenis: option=Option 1.

Kaip mygtukus taip pat galima naudoti paveiksliukus:

<INPUT TYPE="image" SRC="/icons/button.gif" NAME="install" VALUE="Install Program">

Kai nuspaudžiamas mygtukas-paveiksliukas, peržiūros programa perduoda spragtelėjimo koordinates:

install.x=250&install.y=20

Pastebėkime, kad kiekvienas lauko informacijos elementas atskiriamas "&" simboliu.

Atsisakymo mygtukas ištrina visą informaciją, kurią įvedė vartotojas. Jis naudojamas norint panaikinti visus įrašus ir pradėti iš naujo.

 

4.1.4. "Radio buttons" ir "Checkboxes"

"Radio buttons" ir "Checkboxes" elementai naudojami pasiūlyti vartotojui keletą variantų, iš kurių jis gali pasirinkti vieną ar kelis (atitinkamai).

<FORM ACTION="pvz41.pl" METHOD="POST">
Which movies do you want to order: <BR>
Amadeus <INPUT TYPE="checkbox" NAME="amadeus">
The Last Emperor <INPUT TYPE="checkbox" NAME="emperor">
Gandhi <INPUT TYPE="checkbox" NAME="ghandi">
Schindler's List <INPUT TYPE="checkbox" NAME="schindler"><BR>

Jeigu vartotojas pažymi "Checkbox" elementą ir patvirtina formą, pavyzdžiui "Gandhi", peržiūros programa nusiunčia tokius duomenis: gandhi=on.

Reikšmę "on" galima pakeisti naudojant atributą VALUE:

Gandhi <INPUT TYPE="checkbox" NAME="ghandi" VALUE="yes">

Tada , jei pažymėtas Gandhi "Checkbox" elementas, peržiūros programa nusiųs: gandhi=yes.

Vieni "Checkbox" elementai nepriklauso nuo kitų, todėl vienu metu gali būti pažymėti kad ir visi. "Radio button" elementai skiriasi nuo "Checkbox" elementų tuo, kad vienu metu gali būti pažymėtas tik vienas jų:

How do you want to pay for this product:<BR>
Master Card: <INPUT TYPE="radio" NAME="payment" VALUE="MC" CHECKED><BR>
Visa: <INPUT TYPE="radio" NAME="payment" VALUE="Visa"><BR>
American Express: <INPUT TYPE="radio" NAME="payment" VALUE="AMEX"><BR>
Discover: <INPUT TYPE="radio" NAME="payment" VALUE="Discover" ><BR>
</FORM>

Štai keletas taisyklių, kad "Radio buton" elementai veiktų teisingai:

Ir "Checkbox", ir "Radio button" elementams atributas CHECKED nurodo, kuris jų bus pažymėtas pagal nutylėjimą.

   

4.1.5. Meniu ir Prasisukantys sąrašai

Meniu ir prasisukantys (scrolled) sąrašai naudojami atvaizduoti klientui didelį pasirenkamų galimybių kiekį (daug variantų). Štai meniu pavyzdys:

<FORM ACTION="pvz41.pl" METHOD="POST">
Choose a method of payment:
<SELECT NAME="card" SIZE=1>
<OPTION SELECTED>Master Card
<OPTION>Visa
<OPTION>American Express
<OPTION>Discover
</SELECT>

Pasirinkimo meniu ir prasisukantys sąrašai kuriami naudojant SELECT žymę (tag).  Atributas SIZE nurodo meniu ar sąrašas bus vaizduojamas. Jei jis lygus vienam, bus sukurtas meniu, o jei daugiau nei 2 - sąrašas. Tada atributo reikšmė lygi vienu metu matomų sąrašo laukų skaičiui.

Atributas MULTIPLE nurodo, kad vienu metu gali būti pažymėti keli pasirinkimo variantai.

   

4.1.6. Daugelio eilučių tekstiniai laukai

Jie naudojami, kai reikia įvesti daug informacijos.

<FORM ACTION="pvz41.pl" METHOD="POST">
<TEXTAREA ROWS=10 COLS=40 NAME="comments">
</TEXTAREA>

Šiame pavyzdyje sukuriamas prasisukantis tekstinis laukas, susidedantis iš 40 stulpelių ir 10 eilučių matomo ploto.  

 

4.2. Duomenų siuntimas serveriui

Anksčiau mes minėjome MIME tipą application/x-www-form/urlen-coded. Peržiūros programa naudoja šį tipą formos duomenims šifruoti.

Pirmiausia formos elementams, turintiems vardą, nurodytą atributu NAME, priskiriama vartotojo įvesta reikšmė. Tokiu būdu sukuriamos vardo-reikšmės poros (pvz. age=30). Tokios poros tarpusavyje skiriamos simboliu "&".

Antra, jei elemento reikšmė yra įvedamas tekstas, tai gali pasitaikyti simbolių, kurie sumaišytų peržiūros programą, nes yra naudojami valdymo tikslais. Tai specialieji simboliai. Jie pakeičiami atitinkamu šešioliktainiu kodu. Pavyzdžiui, eilutė "Thanks for the help!" bus pakeista tokia: "Thanks%20for%20the%20help%21". Šis procesas kartojamas kiekvienai vardas-reikšmė porai, tam kad sudaryt užklausos eilutę (query string).

Tekstiniams ir slaptažodžio laukams suteikiama įvesto teksto reikšmė. Jeigu nieko nebuvo įvesta, reikšmė lieka "tuščia" (pvz. "name=").

Pažymėtiems "Radio buton" ir "Checkbox" elementams suteikiama VALUE atributo reikšmė. Jei VALUE atributas neapibrėžtas, pagal nutylėjimą priskiriama reikšmė "on". Nepažymėtiems elementams pora vardas-reikšmė nesudaroma. Jie ignoruojami.

Gavusi tokius duomenis, CGI programa turi juos iššifruoti. Iššifravimo būdas yra vienodas abiem (POST ir GET) metodam.

 

4.2.1. GET prieš POST

Yra du būdai formos duomenims persiųsti: GET ir POST. Pagrindinis šių metodų skirtumas yra tai, kokiu būdu formos duomenis gauna CGI programa. Jeigu naudojamas GET metodas, užklausos eilutė (query string) pridedama prie URL, kai klientas pasiunčia pareikalavimą serveriui. Ši užklausos eilutė gali būti gauta naudojant sisteminį kintamąjį QUERY_STRING. Štai paprastas GET pareikalavimas:

GET pvz41.pl?user=Larry%20Bird&age=35&pass=testing HTTP/1.0
Accept: www/source
Accept: text/html
Accept: text/plain
User-Agent: Lynx/2.4 libwww/2.14

Kai jau minėjome antrame skyriuje, užklausos eilutė pridedama prie URL po "?" simbolio. Serveris ją prilygina kintamajam QUERY_STRING.

Pagrindinis GET metodo privalumas tai, kad galima pasiekti CGI programą su užklausa nesinaudojant forma. Tai yra, galima kurti standartines užklausas. Pavyzdžiui, norint sudaryti nuorodą pagal praeitą pavyzdį, reikia tai atlikti taip:

<A HREF="pvz41.pl?user=Larry%20Bird&age=35&pass=testing"> CGI program</A>

Yra dar vienas metodas perduoti duomenis programai, naudojantis URL. Tai pridėtinio kelio metodas.

<A HREF="pvz41.pl/user=Larry%20Bird/age=35/pass=testing"> CGI program</A>

Eilutė "/user=Larry%20Bird/age=35/pass=testing" bus patalpinta sisteminiame kintamajame PATH_INFO. Šis metodas daugiau naudojamas perduoti failų duomenis, nei formų duomenis. (Pavyzdžiui, perduoti failo vardą ar kelią iki jo).

Naudojant GET metodą reikia būti atsargiems, nes peržiūros programa arba serveris gali nukirsti (sutrumpinti) duomenis, jeigu jie viršys maksimalų simbolių skaičių.

Štai paprasto POST pareikalavimo pavyzdys:

POST pvz41.pl HTTP/1.0
Accept: www/source
Accept: text/html
Accept: text/plain
User-Agent: Lynx/2.4 libwww/2.14
Content-type: application/x-www-form-urlencoded
content-length: 35

user=Larry%20Bird&age=35&pass=testing

Pagrindinis POST metodo privalumas yra tai, kad užklausos eilutės dydis nėra ribojamas. Mums nereikia rūpintis, kad serveris ar peržiūros programa nenukarpytų duomenų. CGI programa, norėdama gauti duomenis, pasiųstus POST metodu, turi juos nuskaityti iš standartinio įvedimo įrenginio (STDIN). Tačiau negalima kurti standartinių užklausų.

 

4.2.2. Iššifravimo procesas

Tam kad prieiti prie formos duomenų, juos reikia iššifruoti. Pirmiausia sisteminio kintamojo REQUEST_METHOD pagalba reikia nustatyti, koks duomenų perdavimo metodas buvo panaudotas. Jei tai GET metodas, tai informaciją galima gauti iš aplinkos kintamųjų, priešingu atveju, duomenis reikia nuskaityti iš standartinio įvedimo įrenginio. Duomenų ilgį nurodo aplinkos kintamasis CONTENT_LENGTH. Iššifravimo algoritmas atrodytų taip:

  1. Išsiaiškinti pareikalavimo protokolą (GET ar POST) patikrinant sistemini kintamojo REQUEST_METHOD reikšmę.
  2. Jei protokolas yra GET, nuskaityti užklausos eilutę iš sisteminio kintamojo QUERY_STRING ir/arba pridėtinio kelio informaciją iš PATH_INFO.
  3. Jei protokolas POST, nuskaityti užklausos eilutės dydį naudojantis sisteminiu kintamuoju CONTENT_LENGTH ir nuskaityti atitinkamą duomenų kiekį iš standartinio įvedimo įrenginio.
  4. Išskaidyti užklausos eilutę pagal "&" simbolius, kurie skiria vardas-reikšmė poras.
  5. Iššifruoti šešioliktainius ir "+" simbolius kiekvienoje vardas-reikšmė poroje.
  6. Sukurti vardas-reikšmė porų lentelę, kur vardas atitinka indeksą.

Štai iššifravimo mechanizmą iliustruojantis pavyzdys:

Čia programa common.pl iššifruoja formos duomenis pagal anksčiau pateiktą algoritmą, o programa greeting.pl išveda į ekraną pasisveikinimo tekstą. Ji panaudoja įvestą ir iššifruotą vartotojo vardą.

4.3. Savikontrolės klausimai

  1. Kokie formų privalumai ir trūkumai?
  2. Koks POST metodo privalumas GET metodo atžvilgiu?
  3. Kam naudojamas iššifravimo mechanizmas?

Atsakymai