PAGINA HTML Confrontiamo il codice sorgente della pagina restituitaci dal programma con il programma originale Come si può notare, tutto ciò che è stampato dal programma pippo.pl (esclusa la prima riga) sullo standard output viene inviato al browser via rete come codice HTML da interpretare. Il browser crea quindi la pagina desiderata! BIOINFO3 - Lezione 31 1 RICAPITOLANDO La prima istruzione di print sullo STDOUT eseguita dal programma serve a dire al browser che tutto ciò che riceverà successivamente deve essere interpretato come codice HTML print "Content-type:text/html\n\n"; (ricordarsi i due caratteri di a-capo!) tutto ciò che viene stampato successivamente dal programma è quindi trasferito dal server web, attraverso la rete direttamente al browser ed interpretato da questo come codice HTML HTTPD BROWSER client Output: pagina web Output cgi-bin programma server BIOINFO3 - Lezione 31 programma html 2 PASSAGGIO DI DATI NELL’URL Abbiamo già visto come esistano delle variabili di Perl in cui ricevere gli argomenti. Possiamo eseguire il programma via WEB passando degli argomenti subito dopo il nome del programma e il simbolo di “?” questi sono ancora resi disponibili al programma nella variabile @ARGV. N.B. Bisogna sostituire gli spazi tra gli argomenti con il carattere “+” @ARGV=(“1”,”prova”) $ARGV[0] “1” $ARGV[1] “prova” BIOINFO3 - Lezione 31 3 INVIO DI DATI DA FORM (METODO GET) L’URL con i dati già prefissati può essere utilizzato direttamente come link ipertestuale in una pagina WEB. Ora vediamo invece come sono passati al programma i dati inseriti da un utente in una form, utilizzando il metodo GET. Nella form HTML in cui si chiama il programma dovrà essere specificata la clausola method=GET. BIOINFO3 - Lezione 31 4 FORM Inseriamo i dati richiesti e premiamo il bottone INVIA DATI” BIOINFO3 - Lezione 31 5 METODO GET Con il metodo get il browser crea l’URL del programma da eseguire prendendo l’URL specificata nell’action della form, aggiungendoci “?” e i dati inseriti dall’utente nei campi di input della form nel seguente formato. nomecampo1=valoreinserito1&nomecampo2=valoreinserito2&…... N.B. Anche i valori dei campi di tipo hidden o password sono passati in questo modo e quindi sono chiaramente visibili, con le ovvie conseguenze! BIOINFO3 - Lezione 31 6 VARIABILI D’AMBIENTE Lo script Perl ha a disposizione molte variabili d’ambiente che gli forniscono informazioni sulla modalità CGI-BIN, tra cui proprio i dati ricevuti dalla form. Queste variabili si trovano in un array associativo %ENV e sono settate dal web server httpd prima di mandare in esecuzione il programma CGI richiesto, che così le troverà pronte al momento dell’inizio della sua esecuzione $ENV{DOCUMENT_ROOT} $ENV{HTTP_HOST} $ENV{REMOTE_ADDR} $ENV{QUERY_STRING} $ENV{REQUEST_METHOD} ………. BIOINFO3 - Lezione 31 La root directory del server L’host name del server L’indirizzo IP del client (il visitatore!) I dati passati con il metodo GET Il metodo:GET o POST 7 %ENV Con il seguente programma si stampano i valori delle variabili d’ambiente all’inizio dell’esecuzione di un CGI Notare il contenuto della variabile di ambiente QUERY_STRING, che trasmette al programma tutto ciò che segue il “?” nell’URL che attiva il CGI-BIN BIOINFO3 - Lezione 31 8 RICEZIONE DATI DELLA FORM Questa prima parte del programma serve a creare un array associativo %FORM con i dati ricevuti. Si crea una cella dell’array associativo per ogni campo di input della form. Il nome del campo funge da indice dell’array associativo %FORM, mentre il valore corrispondente è quello inserito dall’utente in quel campo di input della form BIOINFO3 - Lezione 31 9 RICEZIONE DATI DELLA FORM Abbiamo visto che in $ENV{QUERY_STRING} sono contenuti i dati $ENV{QUERY_STRING}=“nome=Nicola&cognome=Cannata” Si splitta la stringa sul carattere “&” inserendo il risultato in @values @values=(“nome=Nicola”,”cognome=Cannata”); Ora si esegue un ciclo foreach per ogni elemento di @values. La variabile $e contiene via via il contenuto delle singole celle di @values. $e=$values[0]=“nome=Nicola” e si splitta la stringa $e sul carattere di “=“ Nel primo ciclo ($nome,$valore)=(“nome”,”Nicola”) e si assegna $FORM{$nome}=$valore $FORM{nome}=“Nicola” Nel secondo ciclo $e=$values[1]=“cognome=Cannata” ($nome,$valore)=(“cognome”,”Cannata”) e si assegna $FORM{$nome}=$valore $FORM{cognome}=“Cannata” BIOINFO3 - Lezione 31 10 ARRAY %FORM Alla fine di questo gruppo di istruzioni il programma cgi-bin ha a disposizione l’array associativo %FORM da cui ricavare tutti i dati inseriti dall’utente nella form (e ovviamente anche i campi hidden). Le chiavi dell’array associativo sono i nomi dei campi di input. Nel programma benvenuto.pl ora si possono usare tranquillamente tali valori ad esempio per stamparli BIOINFO3 - Lezione 31 11 IL METODO POST Abbiamo finora visto la trasmissione di dati ad un programma cgi-bin: direttamente sull’URL del programma dopo il “?”. Gli argomenti sono ricevuti in @ARGV da una form con il metodo GET. I dati sono aggiunti sempre all’URL dopo il “?” e vengono ricevuti come stringa da splittare (prima sul carattere di “&” e poi sul carattere di “=“) nella variabile di ambiente $ENV{QUERY_STRING}. In entrambi i casi i dati vanno a fare parte integrante dell’URL. Con il metodo POST i dati non sono invece visibili nell’URL (e ciò può essere utile per campi hidden o di tipo password). Il programma cgi riceverà i dati direttamente sul suo standard input (STDIN) ancora nel formato nomecampo1=valoreinserito1&nomecampo2=valoreinserito2&…... Dati programma STDIN BIOINFO3 - Lezione 31 STDOUT 12 CODIFICA DEI DATI I dati che il programma riceve sono preventivamente sottoposti ad una codifica per poter essere trasmessi in rete. Sicuramente avrete già visto che tutti gli spazi in un URL sono trasformati in +. Altri caratteri sono trasformati nella forma %xx dove xx è il codice ASCII del carattere (in esadecimale). Se a qualcuno interessassero tutti i codici ASCII gli consiglio di visitare il sito www.asciitable.com. Ad esempio: (space) \t (tab) \n (new-line) / ~ & @ % + %09 %0A %2F %7E %26 %40 %25 (9 decimale) (10 decimale) (38 decimale) (64 decimale) (37 decimale) N.B. Per quanto riguarda il carattere “&” non vengono codificati quelli che fungono da separatore tra le coppie nomecampo=valoreinserito ma solo eventuali altri contenuti nel nome del campo o nei valori inseriti BIOINFO3 - Lezione 31 13 LA FORM Proviamo a scrivere una form che trasmetta al programma cgi i dati col metodo POST E proviamo ad inserire dei dati contenenti spazi e caratteri speciali BIOINFO3 - Lezione 31 14 IL CGI-BIN Scriviamo il programma provapost.pl che deve ricevere i dati BIOINFO3 - Lezione 31 15 IL RISULTATO Eseguiamo il programma premendo il bottone “INVIA DATI” BIOINFO3 - Lezione 31 16 COSA E’ SUCCESSO? La prima istruzione print "Content-type:text/html\n\n"; sappiamo ormai benissimo che serve a segnalare al browser la natura dei dati che sta per ricevere! L’istruzione read(STDIN,$buffer,$ENV{CONTENT_LENGTH}); non l’abbiamo invece mai incontrata. Essa legge dal file associato alla handle passata come primo parametro (quindi dallo standard input STDIN) un numero di caratteri corrispondente a quanto specificato dal terzo parametro (la variabile d’ambiente $ENV{CONTENT_LENGTH} settata dal server, che in questo caso vale 47 ) assegnando i caratteri prelevati alla variabile secondo parametro (e quindi a $buffer) Nello STDIN del programma cgi provapost.pl quindi erano stati scritti 47 caratteri dal server e precisamente due coppie nome=valore separate da &: nome=Qui+Quo+%26+Qua&email=qqq%40paperopoli.com BIOINFO3 - Lezione 31 17 ARRAY %FORM Le istruzioni successive servono ancora alla creazione di un array associativo %FORM destinato a contenere i dati, in modo analogo a quanto visto per il metodo GET @pairs=split(/&/,$buffer); spezza la stringa dei dati (in $buffer) sul carattere “&” inserendo ciascuna coppia nome=valore nell’array @pairs Nel nostro esempio avremo: @pairs=(“nome=Qui+Quo+%26+Qua”, “email=qqq%40paperopoli.com”) ovvero $pairs[0]=“nome=Qui+Quo+%26+Qua” $pairs[1]=“email=qqq%40paperopoli.com” SI effettua quindi un ciclo foreach su ciascun elemento (chiamandolo $pair) dell’array @pairs ed effettuando un secondo split sul carattere “=“ ($nome,$valore)=split(/=/,$pair); BIOINFO3 - Lezione 31 18 ARRAY %FORM Nel primo ciclo: $nome=“nome” $valore=“Qui+Quo+%26+Qua” Nel secondo ciclo: $nome=“email” $valore=“qqq%40paperopoli.com” Prima di effettuare l’assegnamento all’array associativo si devono decodificare i caratteri speciali $valore=~ tr/+/ /; (è equivalente a $valore=~ s/+/ /g; ovvero trasforma ogni carattere “+” contenuto in $valore in uno spazio (ad esempio “Qui+Quo+%26+Qua” diventa “Qui Quo %26 Qua” ) $valore=~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; è un po’ piu complesso ma permette di trasformare ogni stringa %xx nel carattere avente il codice ASCII xx. Il numero esadecimale dopo il % è catturato nella variabile $1 grazie alle parentesi tonde. La funzione hex restituisce il numero decimale corrispondente e la funzione pack lo trasforma nel carattere con quel codice ASCII decimale. Il parametro e permette di avere delle espressioni nella parte che viene sostituita. Senza la e ogni stringa %xx sarebbe stato sostituita da pack("C",hex($1)) e non dal risultato dell’espressione. Senza la g sarebbe stata sostituita solo la prima stringa %xx ma non le successive! BIOINFO3 - Lezione 31 19 RICAPITOLANDO Nel nostro caso, nel primo ciclo avremo finalmente ripristinato il dato originale inserito dall’utente. $valore= “Qui Quo & Qua” Al termine di questo gruppo di istruzioni, che vi consiglio di prendere così com’è e di inserirlo in tutti i vostri programmi cgi che ricevono dati con il metodo POST da una form, nell’array associativo %FORM avremo le due chiavi “nome”,”email”, associate rispettivamente ai valori “Qui Quo & Qua” e “[email protected]” $FORM{“nome”}= “Qui Quo & Qua” $FORM{“email”}= [email protected] E tali valori potranno essere usati a piacere dal programma, ad esempio per inserirli in un database MySQL o per fare delle ricerche. BIOINFO3 - Lezione 31 20 ESERCIZIO Ora vi invito a scrivere un programma perl, attivato via cgi da una form con il metodo POST, che: stampi in una tabella (con bordo) a due colonne: Nella prima riga le intestazioni della tabella: nome nella prima colonna e valore nella seconda. Nelle righe successive: nella prima colonna il nome del campo della form e nella seconda il valore inserito dall’utente. Se l’utente non avesse inserito alcun valore inserire uno spazio HTML ( ) per non “rovinare” esteticamente la tabella. I nomi dei campi devono apparire in ordine alfabetico BIOINFO3 - Lezione 31 21 ESERCIZIO Si richiami il programma con la form generata dal seguente codice HTML BIOINFO3 - Lezione 31 22 ESERCIZIO Ecco la form BIOINFO3 - Lezione 31 23 ESERCIZIO Ed ecco come non deve rispondere il programma cgi-bin, poiché lascia dei “buchi” nella tabella in corrispondenza ai valori non inseriti nella form BIOINFO3 - Lezione 31 24 ESERCIZIO Ecco invece la versione corretta della tabella, senza gli antiestetici buchi! BIOINFO3 - Lezione 31 25 ESERCIZIO Ecco infine il codice del programma! BIOINFO3 - Lezione 31 26 IL MODULO CGI Ora esiste anche un “modulo” del Perl (si tratta di oggetti preconfezionati da usare a “scatola chiusa”; ne vedremo un altro per gestire l’interazione con MySQL) che permette di estrarre in modo molto semplice i parametri ricevuti da una form. Una volta che avete capito come funziona il passaggio dei parametri, potete usare semplicemente questo modulo (sia per GET che per POST)!!! # richiesta di usare il modulo CGI # $i è un nuovo “oggetto” CGI } # ricavo i parametri della form # ‘paper’ era un campo di tipo FILE # il file UPLOADATO viene salvato in una stringa BIOINFO3 - Lezione 31 27 ESERCIZIO Esercizio 16. Progettare una form HTML con tre campi di input (dimensione 10 caratteri, massimo numero di caratteri letto 10) organizzati in una tabella senza bordo di 2 colonne e 3 righe: login (di tipo text), password e re-type password (di tipo password). Premendo il bottone “REGISTRATI ORA” viene attivato un programma iscrivi.pl a cui sono trasmessi i dati della form con il metodo POST. Il programma deve confrontare i due campi di password e se uguali restituire una pagina HTML con titolo “REGISTRAZIONE EFFETTUATA” e con una scritta (ad esempio in <h2>) “Sono stati registrati i dati dell’utente ‘login-dell’utente’ ”. Altrimenti (se le due password sono diverse) restituire una pagina HTML con titolo “REGISTRAZIONE FALLITA” e con la scritta “ATTENZIONE! La password digitata la seconda volta non coincide con la prima. Premere ‘BACK’ e reinserire i dati” BIOINFO3 - Lezione 31 28 RIEPILOGO •Installazione e requisiti dei programmi CGI-BIN •Attivazione e passaggio di argomenti sull’URL •Attivazione da una form: metodo GET •Attivazione da una form: metodo POST •Come ricevere i dati nei tre casi •Il modulo CGI BIOINFO3 - Lezione 31 29