Pagine Dinamiche e Forms

Venerdì, 26 Novembre 2004

OBIETTIVI DELLA LEZIONE

In questa lezione:

  1. impareremo la differenze tra pagine statiche e dinamiche
  2. vedremo come costruire un FORM HTML
  3. vedremo come vengono passati i dati ad una CGI

Client e Server

Il web browser che ci permette di inserire i dati e li inoltra è detto client o anche user agent. Su di un computer "remoto" detto Server machine è installato un programma detto server che è in grado di fornire al client una pagina HTML in seguito ad una domanda specifica (del client).
Il client non ha nessuna idea di come il server generi il documento. Il server è per il client come una scatola nera. Il client effettua una richiesta e si aspetta un file HTML come risposta.

Pagine statiche vs pagine dinamiche

Nella scorsa lezione abbiamo cominciato a costruire alcune pagine HTML. Le pagine che abbiamo creato ovviamente non cambiano da sole: dobbiamo aprirle con un editor e manualmente editarle. In fondo una pagina HTML è solo un file di testo con qualche TAG che ne organizza il contenuto e la visualizzazione. Come è possibile che esistano allora pagine (file di testo con tag) statiche e pagine dinamiche?

E' solo una questione terminologica:

Come fa il programma CGI a generare automaticamente le pagine? Nei casi più semplici esegue una istruzione di sistema e ne ritorna il risultato. Esempio: i primi contatori del numero di accessi ad una data pagina erano semplici script di shell Unix che una volta invocati leggevano da un file il numero di accessi effettuati in precedenza, ne incrementavano il valore e producevano una pagina contenete il valore numerico.

Un alternativa al programma CGI autonomo, è quella dei moduli del server, software che lavorano in cooperazione con il server HTTP. Tipici moduli sono PHP, ASP, ... Come funzionano:

Dispense: 1-PagineDinamiche_new.pdf

FORMS

  • Dispense: 2-FORMSinHTML.pdf
  • CGI

    CGI="common gataway interface" è un metodo di interazione standard tra il client ed un programma lato server. E' indipendente dal: E' sostanziamente una serie di convenzioni che fanno si che un web server sappia come rispondere a richieste del tipo: www.dti.unimi.it/~sassi/LIA2004/provaform.php
    I file CGI sono riconosciuti dal web server perchè sono contenuti in una cartella specifica sul server o perché terminano con una estensione standard (.cgi, .php, .asp, ...).
    Lo standard CGI prevede che, se al server viene richiesta una cartella sensa specificare quale file di quella cartella si desideri, il server inoltri il file "index.htm" contenuto in quella cartella (se esiste) [la cosa è leggermente più complicata, ma per adesso ci basta ricordare questa informazione]. Come dicevamo prima, un programma CGI ritornare la pagina HTML compilata dinamicamente al server WEB scrivendo sullo stdout. Lo scambio di informazioni tra il programma CGI ed un form HTML avviene attraverso due modalità HTTP possibili: GET e POST.

    GET

    I dati che il client vuole inviare alla CGI vengono codificati e aggiunti all'URI. (scritti in fondo all'indirizzo come se ne fossero una parte).

    Convenzione CGI:

    URI + ? + controllo1=valorecontrollo1 +	& + controllo2=valorecontrollo2 + & + ...
    

    Esempio:

    http://www.dti.unimi.it/~sassi/LIA2004/provaform.php?nome=giovanni&cognome=rossi&matricola=123456
    

    Lo standard CGI prevede che i caratteri dopo il "?" vengano copiati dal server nella variabile di ambiente "QUERY_STRING". Ogni programma CGI deve quindi estrare i valori dalla variabile di ambiente e decodificarli opportunamente.
    ATTENZIONE alcuni sistemi operativi limitano il numero di caratteri di una variabile di ambiente a 256. Se prevedete di doverne inoltrare di più non usate GET: verrebbero troncati e mai ricevuti dal programma!

    POST

    I dati vengono posti nel body della richiesta HTTP. Risultato: l'URI non cambia.

    Esempio:

    http://www.dti.unimi.it/~sassi/LIA2004/provaform.php

    Il metodo POST non ha nessun limite sulla dimensione dei dati da trasferire. Lo standar CGI prevede che il server debba estrarre la stringa dei valori dei controlli dal body della richiesta HTTP e copiarla sullo stdin. Il numero dei caratteri posti dal server sullo stdin viene posto nella variabile di ambiente "CONTENT_LENGTH".

    Esempi

    Vediamo due esempi di comunicazioni HTTP:

    GET

    Richiesta del client:
    GET /~sassi/LIA2004/provaform.php?nome=Giovanni&cognome=Rossi&matricola=123456 HTTP/1.1
    Host: www.dti.unimi.it
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.6) Gecko/20040206 Firefox/0.8
    Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml, [...]
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 300
    Connection: keep-alive
    
    Risposta del server:
    HTTP/1.x 200 OK
    Date: Mon, 19 Apr 2004 07:33:48 GMT
    Server: Apache/1.3.26 (Unix) Debian GNU/Linux PHP/4.1.2 mod_ssl/2.8.9 OpenSSL/0.9.6g mod_perl/1.26
    X-Powered-By: PHP/4.1.2
    Keep-Alive: timeout=15, max=100
    Connection: Keep-Alive
    Transfer-Encoding: chunked
    Content-Type: text/html; charset=iso-8859-1
    
    <html>
    <head>
    <title>Prova FORM. La tua matricola è
    ...
    

    POST

    Richiesta del client:
    POST /~sassi/LIA2004/provaform.php HTTP/1.1
    Host: www.dti.unimi.it
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.6) Gecko/20040206 Firefox/0.8
    Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml, [...]
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 300
    Connection: keep-alive
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 44
    
    nome=Giovanni&cognome=Rossi&matricola=123456
    
    Risposta del server:
    HTTP/1.x 200 OK
    Date: Mon, 19 Apr 2004 07:33:54 GMT
    Server: Apache/1.3.26 (Unix) Debian GNU/Linux PHP/4.1.2 mod_ssl/2.8.9 OpenSSL/0.9.6g mod_perl/1.26
    X-Powered-By: PHP/4.1.2
    Keep-Alive: timeout=15, max=99
    Connection: Keep-Alive
    Transfer-Encoding: chunked
    Content-Type: text/html; charset=iso-8859-1
    
    <html>
    <head>
    <title>Prova FORM. La tua matricola è
    ...
    

    Alcuni suggerimenti

    Per visualizzare la risposta di un web server alla richiesta del client, potete utilizzare il client telnet PuttyTel.
    Per esempio, dopo averlo lanciato specificate l'Hostname (www.dti.unimi.it), la porta (80), il protocollo (RAW) e specificate "Close window on exit": NEVER.
    Quindi una volta aperta la finestra telnet (potrebbe non apparire nulla) digitate, ad esempio,
    GET / HTTP/1.0
    e premete enter due volte.

    Ad esempio, una richiesta GET minimale allo script PHP dell'esercizio 1

    GET /~sassi/LIA2004/provaform.php?nome=Giovanni&cognome=Rossi&matricola=123456 HTTP/1.0
    

    ... e una richiesta POST minimale:

    POST /~sassi/LIA2004/provaform.php HTTP/1.0
    Host: www.dti.unimi.it
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 44
    
    nome=Giovanni&cognome=Rossi&matricola=123456
    

    Controlli per FORM HTML

    INPUT

    SELECT

    TEXTAREA

    <textarea cols=40 rows=5 name="testo">
    Testo che si trova già digitato in una frase molto lunga.
    </textarea>
    

    Un esempio: Form che scarica una pagina TELEVIDEO

    <html>
    <head>
    <title>Esempio di form che accede a Televideo</title>
    </head>
    <body>
    VISUALIZZA LA PAGINA TELEVIDEO
    <br />
    <form method="get" action="http://www.televideo.rai.it/nazionale/solotesto.asp">
    <table>
        <tr>
        <th>Pagina Televideo:</th>
        <td><input type="text" name="tlv"></td>
        </tr>
        <tr>
        <th></th>
        <td><input type="submit" value="Visualizza"></td>
        </tr>
    </table>
    <input type="hidden" name="sottop" value="01">
    </form>
    </body>
    </html>
    
    

    Il nostro primo script PHP

    <html>
    <head>
    <title>Prova FORM. La tua matricola è
    <?php
    print " " . $_REQUEST['matricola'] . ".";
    ?>
    </title>
    </head>
    <body>
    Ben arrivato
    <?php
    print "<b>" . $_REQUEST["nome"] . " " . $_REQUEST['cognome'] . "</b>";
    ?>
    &nbsp;ti stavo aspettando. <br />
    Il tuo numero di matricola è nel titolo.
    </body>
    </html>
    

    Lab

    Esercizio 1

    Costruire una pagina HTML che contenga un FORM che richieda all'utente di inserire nome, cognome e matricola. Il FORM deve inviare i dati con il metodo GET all'indirizzo http://www.dti.unimi.it/~sassi/LIA2004/provaform.php; i dati devono essere contenuti in controlli chiamati rispettivamente "nome", "cognome" e "matricola".

    Una volta ottenuta la risposta corretta dal server, rifate l'esercizio utilizzando il metodo POST per l'invio dei dati. Cosa cambia?

    Esercizio 2

    Dal sito www.trenitalia.com è possibile ottenere informazioni circa l'orario ferroviario. La pagina è però appensantita da immagini e applets. Scriviamo noi una nostra interfaccia!

    Ispirandosi all'interfaccia di Televideo vista a lezione, preparare una pagina HTML che contenga un FORM che permetta di ottenere dal server http://orario.trenitalia.com/webapp/trenitalia/TimeTable l'orario di un particolare treno.

    I controlli da fornire con il metodo POST (o GET, in questo caso funzionano entrambi) sono:

    • "stazin" (stazione di partenza),
    • "stazout" (stazione di arrivo),
    • "datag" (giorno di partenza),
    • "datam" (mese di partenza),
    • "dataa" (anno di partenza),
    • "timsh", (ora di partenza),
    • "timsm" (minuti dopo l'ora di partenza),
    • "lang" (linguaggio; suggerimento: predisporre un controllo hidden con il valore predefinito "it"),
    • "nreq" (numero di risultati da visualizzare).

    Esercizio 3

    Il signor Rossi è ossessionato dai consumi elettrici di casa e tenta in ogni modo di ridurli. A questo fine introduce spesso migliorie all'impianto (introduzione lampadine a basso consumo, elettrodomestici più avanzati, ...).
    A fronte di ogni miglioria si annota su di un foglio la data e la lettura del contatore.
    Sapendo che siete dei brillanti studenti, vi commissiona il programma TabellaConsumi.java che gli permetta di tenere nota delle lettura e creare a richiesta una pagina HTML con una tabella riassuntiva.
    Il programma una volta eseguito, deve mostrare il testo "PRONTO> " e rimanere in attesa di un comando. Una volta eseguito il comando deve tornare di nuovo nello stato di attesa (dovete scrivere un semplice interprete di comandi). I comandi che il programma accetta sono:

    1. 'E': termina il programma
    2. 'N': crea un file di testo vuoto consumienel.txt. Se il file esiste già chiede conferma prima di cancellarlo. [Suggerimento: utilizzate i metodi createNewFile() e delete() della classe File].
    3. 'C': cancella il file di testo consumienel.txt. Chiede sempre conferma prima di cancellare. [Suggerimento: utilizzate il metodo delete() della classe File].
    4. 'A': aggiunge una lettura al file consumienel.txt. La lettura contiene quattro valori: giorno, mese, anno e KWh consumati. I valori vanno in colonne separate da tabulazioni ('\t') Suggerimento: per prima cosa chiedete il valore della lettura all'utente, quindi aprite il file e aggiungetela in fondo. Il file viene chiuso dopo ogni lettura aggiunta. [Suggerimento: create ogni volta un nuovo stream FileWriter in modalità append (vedere l'help in linea). Alla fine utilizzate il metodo close].
    5. 'H': crea il file HTML consumienel.html che DEVE contenere una tabella HTML in cui ogni riga contenga una lettura differente (tutte quelle che sono nel file consumienel.txt). Le colonne devono contenere: numero della lettura (progressivo), la data e il numero di KWh consumati.
    6. Per effettuare l'input da console, prendete spunto dall'esempio Lune.java (Esercizio 3 della lezione 2).

    ©2004 Roberto Sassi