Rubrica WEBTECH

CGI Corner

La gestione delle form

Eccoci arrivati al secondo appuntamento sulla programmazione della Common Gateway Interface (CGI). Questa volta vedremo come si gestiscono le form, quindi allacciatevi le cinture.

di Michele Beltrame


Le form, queste sconosciute

Una delle più importanti applicazioni della tecnologia CGI è, come ho già scritto nell'articolo precedente, la possibilità di gestire l'input da parte dell'utente tramite le form ( o i form, a seconda di come preferire chiamarle... non so quale sia la versione corretta in realtà ;-) ). Con le form è infatti possibile gestire guestbook, questionari, ordini in linea, sondaggi, ricerche , e tutta una serie di operazioni che richiedono l'interazione tra utente e server.

Chiariamo anzitutto che l'unico formato di dati inviabile tramite form è testo. In realtà estensioni introdotte con la versione 2.0 di Netscape permettono anche l'upload tramite form di qualsiasi tipo di file.

La prima cosa da imparare è come si costruiscono le form in HTML. Quindi tratterò anzitutto questo argomento, e poi passero alla loro gestione, fornendo anche alcuni esempi.


La creazione delle form

Il tag fondamentale per la crezione delle form è, guarda caso, <FORM>. Esso è infatti il contenitore nel quale sono contenuti tutti gli altri tag utilizzati per la defizione della form. Un semplice esempio di form <FORM> è il seguente:

<FORM ACTION="/cgi-bin/formproc.pl" METHOD="GET">
Qui vanno inseriti i controlli ed il testo della form
</FORM>

Vediamo la descrizione dettagliata dei parametri accettati dal tag :

  • ACTION="path/nomeprogramma" - Questo parametro indica dove il nome e l'ubicazione (la URL praticamente...) del programma CGI che verrà eseguito al momento dell'invio della form (tramite il controllo submit, che descriverò in seguito). Il programma specificato qui dovrà occuparsi di processare tutti i dati che gli verranno passati dal client.
  • METHOD="metodo di passaggio dei dati" - Tramite questo parametro si specifica il modo in cui vengono passati i dati della form dal client al programma CGI. I metodi sono due: GET e post. Le differenze tra i due metodi sono discusse nella sezione Come vengono passati i dati al CGI di questo stesso articolo.
  • ENCTYPE="tipo di codifica" - Questo parametro è opzionale e permette di specificare il tipo di codifica con cui i dati vengono passati dalla form al programma CGI. Al momento solo due tipi di condifica sono universalmente riconosciuti: application/x-www-form-urlencoded (che è il valore di default) e multipart/form-data (che permette l'upload di file, a patto che il client sia Netscape v2.0 o superiore).


Controlli

Tutti i bottoni, le text area, le check box, le list box, i radio button e tutti le altre parti della form che si occupano di interagire con l'utente sono chiamati controlli ( o almeno io li chiamo così, traducendo lettarlmente l'inglese controls ). I controlli sono definiti tramite il tag <INPUT>, che accetta fondamentalmente tre parametri: TYPE, che specifica il tipo del controllo; NAME, che permette di identificare il controllo assegnandoli un nome; VALUE, che assegna un valore di default al controllo. Vi sono inoltre altri paramentri, che dipendono dal tipo del controllo.

Vediamo i vari tipi di controlli:

  • Bottoni[Bottone] - Sono i controllo più classici, la ci pressione porta all'esecuzione di una certa azione. La sintassi per l'uso dei bottoni è la seguente:

    <INPUT TYPE="tipobottone" NAME="nomebottone" VALUE="valore">

    Vi sono quattro tipi di bottone: button, image, submit, reset.
    Se il bottone è di tipo submit, alla sua pressione la form verrà inviata al server. È possibile avere più di un bottone submit:

    <INPUT TYPE="submit" NAME="invia" VALUE="opzione1">
    <INPUT TYPE="submit" NAME="invia" VALUE="opzione2">

    La form verrà inviata al server alla pressione di uno qualunque dei due bottoni, ma verrà passata al programma CGI la stringa value=opzione1 nel primo caso e value=opzione2 nel secondo caso. Ricordo che il campo VALUE serve anche per assegnare una label al bottone.
    I bottoni di tipo reset hanno la sola funzione di cancellare tutti i campi delle form modificati dall'utente, riportandoli al loro valore di default ( in pratica vengono cancellati tutti i contenuti delle textarea, delle input line, ...). Il campo VALUE, come nel caso dei bottoni di tipo submit assegna una label al bottone.
    I bottoni di tipo image permettono l'inserimento nella form di immagini clikkabili, che si comportano cioé come bottoni. La sintassi è la seguente:

    <INPUT TYPE="image" SRC="/stuff/images/butn.gif" NAME="Pesce" VALUE=="Palla">

    Questo bottone si presenterà come un'immagine alla cui pressione verranno inviate le coordinate del click se il browser è di tipo grafico (es. Netscape):

    Pesce.x=25&Pesce.y=67

    Se invece il browser è testuale (es. Lynx) verrà inviato il campo VALUE:

    Pesce=Palla

    Il bottone di tipo button, infine, è utilizzato quasi esclusivamente per l'interazione con programmi JavaScript, quindi mi limito a nominarlo.

  • Input Line[Input line] - Sono dei controlli che permettono all'utente di immettere su una sola riga del testo, che verrà poi inviato al programma CGI. Vi sono due tipi di input line: text e password. Sintatticamente i due tipi sono identici, solo che nel primo caso l'utente vede quello che sta scrivendo, mentre nel secondo caso vede sono asterischi (*), o quello che il browser mette al posto del testo. Il secondo tipo di input line andrà quindi bene per password o per testi che comunque non dovrebbero essere visti da qualcuno che passa davanti al monitor del client. La sintassi di base delle input line è quella dell'esempio seguente:

    <INPUT TYPE="text" NAME="testoprova">

    oppure, se si tratta di testo che non deve essere visto:

    <INPUT TYPE="password" NAME="testoprova">

    Al momento dell'invio della form, il programma CGI riceverà una strigna del tipo:

    testoprova=testo+immesso+dal+client

    È possibile specificare anche un campo VALUE, che assegnerà all'input line una stringa di default, che l'utente potrà poi modificare. Vi sono inoltre i campi SIZE e MAXLENGTH. SIZE indica la lunghezza in caratteri dell'input line, MAXLENGTH indica la lunghezza massima della stringa che si può immettere. Se MAXLENGTH è più grande di SIZE il testo scorre e rimangono comunque visibili solo SIZE caratteri. Se SIZE non viene specificato, il valore di default è 20, se MAXLENGTH non viene specificato la stringa può assumere lunghezza illimitata.

  • Textarea[Textarea] - Le textarea sono dei controlli che permettono l'immissione di testo su più righe. Vediamo subito un esempio :

    <TEXTAREA ROWS=15 COLS=30 NAME="commenti">
    Qui ci va l'opzionale testo di default </TEXTAREA>

    Come si può intuire, il campo ROWS permette di specificare la dimensione verticale (in righe) della textarea, mentre il campo COLS permette di specificarne la dimensione orizzontale (in colonne). Al momento dell'invio della form la seguente stringa viene inviata al server:

    commenti=tutto+il+testo+scritto+dal+client

  • Campi nascosti - Si usano per passare al programma CGI valori fissi che non vengono visti dall'utente. Sono utili ad esempio per permettere l'identificazione di una specifica form da parte di un programma CGI che viene utilizzato per gestire più form. Vediamo un esempio:

    <INPUT TYPE="hidden" NAME="identificazione" VALUE="sondaggio">

    Al momento dell'invio della FORM il programam CGI riceverà la stringa :

    identificazione=sondaggio

  • Checkbox[Check Box] - Le checkbox sono switch binari, assumono cioé due stati: on e off. Facendo click sulla casella che identifica la checkbox se ne cambia lo stato. Solitamente assumono l'aspetto di bottoncini quadrati che sprofondano quando vengono attivati. Il seguente esempio :

    È la prima volta che visiti questo sito?
    <INPUT TYPE="checkbox" NAME="primavolta">

    creerà una checkbox che, al momento dell'invio della form, invierà al programma CGI la stringa :

    primavolta=on

    se l'utente ha attivato la checkbox. È possibile utilizzare qualsiasi altra stringa al posto di "on" (che è quella di default) impostando il parametro VALUE. Ad esempio utilizzando VALUE="activated" il programma CGI riceverà la stringa :

    primavolta=activated

  • È possibile inserire un parametro CHECKED in ogni checkbox, che farà si che la checkbox sia di default attivata, anziché disattivata

  • Radio button[Radio Button] - I radio button sono bottoncini, tipicamente di forma circolare, collegati l'uno all'altro. Può essere attivato un solo radio button alla volta quindi, quando l'utente ne attiva uno, quello attivo in precedenza viene automaticamente disattivato. Visivamente un radio button ha l'aspetto di un cerchietto vuoto quando è disattivato, e di un cerchietto pieno quando viene attivato. Vediamo, come al solito, un esempio :

    Ti è piaciuto questo sito?
    <INPUT TYPE="radio" NAME="gradimento" VALUE="Moltissimo">
    <INPUT TYPE="radio" NAME="gradimento" VALUE="Molto" CHECKED>
    <INPUT TYPE="radio" NAME="gradimento" VALUE="Poco">
    <INPUT TYPE="radio" NAME="gradimento" VALUE="Per niente">

    Questo frammento di form manda al programma CGI, quando la form viene inviata al server, un stringa del tipo :

    gradimento=Poco

    dove gradimento può essere Poco, Per niente, Moltissimo o Molto a seconda della scelta dell'utente. Di default viene attivato il radio button in cui è specificato il parametro CHECKED. Se tale parametro non è specificato per nessun radio button, essi risulteranno di default tutti disattivati. È importante osservare che tutti i radio button dello stesso gruppo devono avere lo stesso NAME. Se il NAME è diverso, il browser assumerà che vi sia più di un gruppo di radio button e si comporterà di conseguenza, inviando più stringhe.

  • Liste scorrevoli[Lista scorrevole] - Si tratta di liste di elementi da cui è possibile sceglierne uno. Vediamo un esempio di implementazione:

    <SELECT NAME="film" SIZE=4>
    <OPTION SELECTED>Intrigo a Stoccolma
    <OPTION>Viuuulentemente mia
    <OPTION>Ecceziuuunale
    <OPTION>Attila flagello di Dio
    <OPTION>Laguna blu
    </SELECT>

    Al momento dell'invio della form, il programma CGI ricevera una stringa del tipo:

    film=Ecceziuuunale

    a seconda del film che l'utente ha scelto. Se un tag OPTION ha il parametro SELECTED specificato, l'opzione relativa ad esso sarà selezionata di default. Nel tag SELECT è possibile specificare il parametro MULTIPLE, che permette all'utente di selezionare più di un'opzione. Il parametro SIZE del tag SELECT indica quante righe della lista vengono visualizzate alla volta; alle righe che eccedono il limite imposto dal SIZE si accede tramite le scrollbar, scorrendo cioé la lista.

  • Menu[Menu] - I menu a scomparsa hanno lo stesso funzionamento delle liste scorrevoli. Per usarli basta specificare SIZE=1 nel tag SELECT


Come vengono passati i dati al CGI

I dati vengono passati al programma CGI al momento dell'invio della form (tramite un controllo di tipo submit). Ci sono, come accennato in apertura di articolo, due possibili modalità il passaggio dei dati: GET e POST. Con il metodo GET i dati vengono attaccati tramite un punto di domanda ( ? ) alla URL che chiama il programma CGI e vengono poi immagazzinati nella variabile d'ambiente QUERY_STRING, direttamente accessibile dal CGI. Se invece si usa il metodo POST i dati vengono inviati allo standard input del programma CGI. Così a occhio si potrebbe pensare che non ci sia alcuna differenza effettiva tra i due metodi, ma non è proprio così. Infatti la lunghezza delle query (cioé le richieste fatte dal client al server di eseguire un determinato programma CGI o di inviare un determinato documento) effettuate con il metodo GET è in genere limitata a qualche centinaio di caratteri, in quando prima o poi il browser o il server tagliano la URL causando la conseguente perdita di parte dei dati. Il metodo GET ha tuttavia anche un vantaggio rispetto al metodo POST: i dati possono essere passati al CGI anche immettendoli manualmente nella casella della URL, il che consente ad esempio di salvare un bookmark che richiama un CGI. La scelta del metodo dipende dalle proprie esigenze, comunque se la form prevede il passaggio di una limitata quantità di dati è meglio utilizzare il metodo GET, mentre se i dati sono molti sarà necessario ricorrere al metodo POST.

Vediamo ora un esempio di una query effettuata con metodo GET :

GET /cgi-bin/test.pl?computer=PowerPC&film=Attila+flagello+di+Dio&sistema=Linux HTTP/1.0
Accept: www/source
Accept: text/html
Accept: text/plain
User-Agent: Mozilla/3.01 (X11; I; Linux 2.1.13 i586)

Ed ecco la stessa query effettuata invece col metodo POST :

POST /cgi-bin/test.pl HTTP/1.0
Accept: www/source
Accept: text/html
Accept: text/plain
User-Agent: Mozilla/3.01 (X11; I; Linux 2.1.13 i586)
Content-type: application/x-www-form-urlencoded
Content-length: 66

computer=PowerPC&film=Attila+flagello+di+Dio&sistema=Linux

Il programma CGI può riconoscere se la query è stata fatta con metodo GET o POST leggendo al variabile d'ambiente QUERY_STRING, che conterrà appunto la stringa GET o la stringa POST. In ogni caso, indipendentemente dal fatto che venga usato il metodo GET od in metodo POST, vanno fatte alcune osservazioni sulla stringa contente i dati, che è rappresentata, come detto prima, dalla variabile QUERY_STRING se il metodo è GET, oppure dal contenuto dello standard input (STDIN) se il metodo è POST :

  • I dati vengono passati nella forma nomevariabile=valore, ed ogni variabile è separata dall'altra tramite una & .

  • Ogni spazio è sostituito da un segno + .

  • Ogni carattere non alfanumerico è sostituito dal corrispondente valore esadecimale preceduto da un segno % .


Decodificare una query

Scrivere il codice per decodificare una query proveniente da una form può essere un lavoro estremamente seccante, a seconda del linguaggio utilizzato. In Perl la cosa può risultare abbastanza comoda, in C++ decisamente lo è meno. Se non avete tempo o voglia di scrivervi una funzione per la decodifica potete utilizzare, se programmate in Perl, la cgi-lib.pl di Steven E. Brenner. Per gli altri linguaggi potete dare un'occhiata qui.


Il terzo metodo...

Sorpresa! Esiste un terzo metodo (oltre GET e POST) di invio delle query, anche se non funziona proprio con tutti i browser. Si tratta di uno scamuffo che permette di inviare i dati raccolti tramite una form ad una mailbox anziché ad un programma CGI. Faccio presente che anche con questo metodo i dati giungono alla mailbox del destinatario codificati (cioé con il + al posto dello spazio, la & che separa i campi, etc...). Per quanto riguarda l'implementazione, si tratta di fare solo una piccola modifica al tag FORM. Ecco un esempio :

<FORM ACTION="mailto:mentat@italpro.com" METHOD="POST">
Qui vanno inseriti i controlli della form
</FORM>

Come si può vedere, in realtà il metodo è comunque POST, ma l'action ha una forma lievemente diversa.


Conclusione...

Anche la seconda puntata è andata. Spero di essere stato abbastanza chiaro nella spiegazione, anche se ho dovuto sintetizzare in un unico articolo un argomento che meriterebbe molto più spazio. Nel prossimo numero tratterò i Server Side Include, con cui si realizzano contatori ed altre cosucce simpatiche.


Bibliografia
Larry Wall / Randal L. Schwartz - "Programming perl" - O'Reilly & Associates
Shishir Gundavaram - "CGI Programming on the World Wide Web" - O'Reilly & Associates
Apache Documentation - http://www.apache.org/docs/
Bjarne Stroustrup - "The C++ Programming Language - Second Edition" - Addison-Wesley

Michele Beltrame è Webmaster del sito ItalPro ed è raggiungibile su Internet tramite la redazione


Copyright © 1996 BETA. Tutti i diritti riservati.


Precedente Principale Sommario Informazioni Redazione Browser Successivo