2. Le basi
In questo capitolo presentiamo le basi della programmazione web. Il suo scopo principale è quello di far scoprire i principi fondamentali della programmazione web prima di metterli in pratica con un linguaggio e un ambiente specifici. Presenta numerosi esempi che è consigliabile provare per “assimilare” gradualmente la filosofia dello sviluppo web.
2.1. I componenti di un’applicazione web
![]() |
Numero | Ruolo | Esempi comuni |
OS Server | Linux, Windows | |
Server Web | Apache (Linux, Windows) IIS (NT), PWS (Win9x) | |
Script eseguiti sul lato server. Possono essere eseguiti da moduli del server o da programmi esterni al server (CGI). | PERL (Apache, IIS, PWS) VBSCRIPT (IIS, PWS) JAVASCRIPT (IIS, PWS) PHP (Apache, IIS, PWS) JAVA (Apache, IIS, PWS) C#, VB.NET (IIS) | |
Database - Può trovarsi sullo stesso computer del programma che la utilizza oppure su un altro computer tramite Internet. | Oracle (Linux, Windows) MySQL (Linux, Windows) Access (Windows) SQL Server (Windows) | |
OS Client | Linux, Windows | |
Browser Web | Netscape, Internet Explorer | |
Script eseguiti sul lato client all'interno del browser. Questi script non hanno alcun accesso ai dischi del computer client. | VBscript (IE) JavaScript (IE, Netscape) PerlScript (IE) Applet JAVA |
2.2. Scambio di dati in un’applicazione web con modulo
![]() |
Numero | Ruolo |
Il browser richiede un URL per la prima volta (http://machine/url). Non è stato passato alcun parametro. | |
Il server Web gli invia la pagina Web corrispondente a questo URL. Può essere statica oppure generata dinamicamente da uno script del server (SA) che potrebbe aver utilizzato il contenuto di database (SB, SC). In questo caso, lo script rileverà che URL è stato richiesto senza il passaggio di parametri e genererà la pagina iniziale WEB. Il browser riceve la pagina e la visualizza (CA). Gli script lato browser (CB) potrebbero aver modificato la pagina iniziale inviata dal server. Successivamente, attraverso le interazioni tra l’utente (CD) e gli script (CB), la pagina web verrà modificata. In particolare, i moduli verranno compilati. | |
L’utente conferma i dati del modulo, che devono quindi essere inviati al server web. Il browser richiede nuovamente l’URL iniziale o un’altra, a seconda dei casi, e trasmette contemporaneamente al server i valori del modulo. A tal fine può utilizzare due metodi denominati GET e POST. Alla ricezione della richiesta del client, il server avvia lo script (SA) associato all’URL richiesto, script che rileverà i parametri e li elaborerà. | |
Il server fornisce la pagina WEB generata dal programma (SA, SB, SC). Questa fase è identica alla precedente fase 2. Gli scambi avvengono ora secondo le fasi 2 e 3. |
2.3. Alcune risorse
Di seguito è riportato un elenco di risorse che consentono di installare e utilizzare alcuni strumenti per lo sviluppo web. In allegato è disponibile una guida all’installazione di tali strumenti.
- Apache, Installazione e implementazione, O'Reilly | |
- Programmazione in Perl, Larry Wall, O'Reilly - Applicazioni in Perl (CGI), Neuss e Vromans, O'Reilly - la documentazione fornita con Active Perl | |
- Programmazione Web con PHP, Lacroix, Eyrolles - Manuale d'uso di PHP scaricabile dal sito di PHP | |
- Interfaccia tra WEB e il database in WinNT, Alex Homer, Eyrolles | |
- JAVA Servlets, Jason Hunter, O'Reilly - Programmazione di rete con Java, Elliotte Rusty Harold, O'Reilly - JDBC e Java, George Reese, O'Reilly | |
- Il manuale di MySQL è disponibile sul sito di MySQL - Oracle 8i su Linux, Gilles Briard, Eyrolles - Oracle 8i su NT, Gilles Briard, Eyrolles |
2.4. Notazioni
Di seguito, daremo per scontato che siano stati installati alcuni strumenti e adotteremo le seguenti notazioni:
notazione | significato |
radice dell'albero di directory del server Apache | |
radice delle pagine web fornite da Apache. È in questa radice che devono trovarsi le pagine web. Pertanto, l'indirizzo http://localhost/page1.htm corrisponde al file <apache-DocumentRoot>\page1.htm. | |
radice dell’albero associata all’alias cgi-bin, dove è possibile inserire gli script CGI per Apache. Pertanto, l'URL http://localhost/cgi-bin/test1.pl corrisponde al file <apache-cgi-bin>\test1.pl. | |
radice delle pagine Web generate da PWS. È in questa directory principale che devono trovarsi le pagine Web. Pertanto, URL http://localhost/page1.htm corrisponde al file <pws-DocumentRoot>\page1.htm. | |
radice dell'albero del linguaggio Perl. L'eseguibile perl.exe si trova in genere in <perl>\bin. | |
radice dell'albero del linguaggio PHP. L'eseguibile php.exe si trova solitamente in <php>. | |
radice della struttura ad albero di Java. I file eseguibili relativi a Java si trovano in <java>\bin. | |
radice del server Tomcat. Esempi di servlet si trovano in <tomcat>\webapps\examples\servlets ed esempi di pagine in JSP in <tomcat>\webbapps\examples\jsp |
Per ciascuno di questi strumenti, si rimanda all’appendice che fornisce indicazioni per la loro installazione.
2.5. Pagine web statiche, pagine web dinamiche
Una pagina statica è rappresentata da un file HTML. Una pagina dinamica, invece, viene generata «al volo» dal server web. In questo paragrafo proponiamo diversi test con vari server web e diversi linguaggi di programmazione per dimostrare l’universalità del concetto web.
2.5.1. Pagina statica HTML (HyperText Markup Language)
Consideriamo il seguente codice HTML:
<html>
<head>
<title>essai 1 : une page statique</title>
</head>
<body>
<center>
<h1>Une page statique...</h1>
</body>
</html>
che genera la seguente pagina web:
I test

test1
- avviare il server Apache
- inserire lo script essai1.html in <apache-DocumentRoot>
- visualizzare URL http://localhost/essai1.html con un browser
- arrestare il server Apache
test2
- avviare il server PWS
- inserire lo script essai1.html in <pws-DocumentRoot>
- visualizzare l’URL http://localhost/essai1.html con un browser
2.5.2. Una pagina ASP (Active Server Pages)
Lo script essai2.asp:
<html>
<head>
<title>essai 1 : une page asp</title>
</head>
<body>
<center>
<h1>Une page asp générée dynamiquement par le serveur PWS</h1>
<h2>Il est <% =time %></h2>
<br>
A chaque fois que vous rafraîchissez la page, l'heure change.
</body>
</html>
genera la seguente pagina web:

Il test
- avviare il server PWS
- inserire lo script essai2.asp in <pws-DocumentRoot>
- richiedere l'URL http://localhost/essai2.asp con un browser
2.5.3. Uno script PERL (Practical Extracting and Reporting Language)
Lo script essai3.pl:
#!d:\perl\bin\perl.exe
($secondes,$minutes,$heure)=localtime(time);
print <<HTML
Content-type: text/html
<html>
<head>
<title>essai 1 : un script Perl</title>
</head>
<body>
<center>
<h1>Une page générée dynamiquement par un script Perl</h1>
<h2>Il est $heure:$minutes:$secondes</h2>
<br>
A chaque fois que vous rafraîchissez la page, l'heure change.
</body>
</html>
HTML
;
La prima riga è il percorso dell'eseguibile perl.exe. Se necessario, va modificata. Una volta eseguito da un server Web, lo script genera la seguente pagina:

Il test
- server Web: Apache
- Per informazioni, visualizzare il file di configurazione srm.conf o httpd.conf a seconda della versione di Apache in <apache>\confs e cercare la riga relativa a cgi-bin per individuare la directory <apache-cgi-bin> in cui collocare essai3.pl.
- inserire lo script essai3.pl in <apache-cgi-bin>
- richiedere l'URL http://localhost/cgi-bin/essai3.pl
Da notare che occorre più tempo per visualizzare la pagina perl rispetto alla pagina asp. Ciò è dovuto al fatto che lo script Perl viene eseguito da un interprete Perl che deve essere caricato prima di poter eseguire lo script. Non rimane permanentemente in memoria.
2.5.4. Uno script PHP (Personal Home Page, HyperText Processor)
Lo script essai4.php
<html>
<head>
<title>essai 4 : une page php</title>
</head>
<body>
<center>
<h1>Une page PHP générée dynamiquement</h1>
<h2>
<?
$maintenant=time();
echo date("j/m/y, h:i:s",$maintenant);
?>
</h2>
<br>
A chaque fois que vous rafraîchissez la page, l'heure change.
</body>
</html>
Lo script precedente genera la seguente pagina web:
I test


-
consultare il file di configurazione srm.conf o httpd.conf di Apache in <Apache>\confs
-
a titolo informativo, verificare le righe di configurazione di php
test1
-
avviare il server Apache
-
inserire essai4.php in <apache-DocumentRoot>
-
richiedere l'URL http://localhost/essai4.php
test2
-
avviare il server PWS
-
a titolo informativo, verificare la configurazione di PWS relativa a PHP
-
inserire essai4.php in <pws-DocumentRoot>\php
-
richiedere l'http://localhost/essai4.php di URL
2.5.5. Uno script JSP (Java Server Pages)
Lo script heure.jsp
<% //programma Java che visualizza l'ora %>
<%@ page import="java.util.*" %>
<%
// codice JAVA per calcolare l'ora
Calendar calendrier=Calendar.getInstance();
int heures=calendrier.get(Calendar.HOUR_OF_DAY);
int minutes=calendrier.get(Calendar.MINUTE);
int secondes=calendrier.get(Calendar.SECOND);
// ore, minuti e secondi sono variabili globali
// che potranno essere utilizzate nel codice HTML
%>
<% // codice HTML %>
<html>
<head>
<title>Page JSP affichant l'heure</title>
</head>
<body>
<center>
<h1>Une page JSP générée dynamiquement</h1>
<h2>Il est <%=heures%>:<%=minutes%>:<%=secondes%></h2>
<br>
<h3>A chaque fois que vous rechargez la page, l'heure change</h3>
</body>
</html>
Una volta eseguito dal server web, questo script genera la seguente pagina:

I test
- inserire lo script heure.jsp in <tomcat>\jakarta-tomcat\webapps\examples\jsp (Tomcat 3.x) oppure in <tomcat>\webapps\examples\jsp (Tomcat 4.x)
- avviare il server Tomcat
- richiedere l'http://localhost:8080/examples/jsp/heure.jsp URL
2.5.6. Conclusione
Gli esempi precedenti hanno dimostrato che:
- una pagina HTML può essere generata dinamicamente da un programma. Questo è il vero senso della programmazione web.
- i linguaggi e i server web utilizzati possono essere diversi. Attualmente si osservano le seguenti tendenze principali:
- le combinazioni Apache/PHP (Windows, Linux) e IIS/PHP (Windows)
- la tecnologia ASP.NET su piattaforme Windows che associa il server IIS a un linguaggio .NET (C#, VB.NET, ...)
- la tecnologia dei servlet Java e delle pagine JSP che funzionano con diversi server (Tomcat, Apache, IIS) e su diverse piattaforme (Windows, Linux). È proprio quest’ultima tecnologia che verrà trattata in modo più approfondito nel presente documento.
2.6. Script lato browser
Una pagina HTML può contenere script che verranno eseguiti dal browser. Esistono numerosi linguaggi di scripting lato browser. Eccone alcuni:
Linguaggio | Browser compatibili |
VBScript | IE |
JavaScript | IE, Netscape |
PerlScript | IE |
Java | IE, Netscape |
Prendiamo alcuni esempi.
2.6.1. Una pagina web con uno script VBScript, lato browser
La pagina vbs1.html
<html>
<head>
<title>essai : une page web avec un script vb</title>
<script language="vbscript">
function reagir
alert "Vous avez cliqué sur le bouton OK"
end function
</script>
</head>
<body>
<center>
<h1>Une page Web avec un script VB</h1>
<table>
<tr>
<td>Cliquez sur le bouton</td>
<td><input type="button" value="OK" name="cmdOK" onclick="reagir"></td>
</tr>
</table>
</body>
</html>
La pagina HTML sopra riportata non contiene semplicemente il codice HTML, ma anche un programma destinato ad essere eseguito dal browser che avrà caricato questa pagina. Il codice è il seguente:
<script language="vbscript">
function reagir
alert "Vous avez cliqué sur le bouton OK"
end function
</script>
I tag <script></script> servono a delimitare gli script nella pagina HTML. Questi script possono essere scritti in diversi linguaggi ed è l’opzione language del tag <script> che indica il linguaggio utilizzato. In questo caso è VBScript. Non entreremo nei dettagli di questo linguaggio. Lo script sopra riportato definisce una funzione denominata réagir che visualizza un messaggio. Quando viene chiamata questa funzione? Ce lo indica la seguente riga di codice HTML:
L’attributo onclick indica il nome della funzione da chiamare quando l’utente cliccherà sul pulsante OK. Una volta che il browser avrà caricato questa pagina e l’utente avrà cliccato sul pulsante OK, si otterrà la pagina seguente:

I test
Solo il browser IE è in grado di eseguire gli script VBScript. Netscape richiede dei componenti aggiuntivi per farlo. È possibile eseguire i seguenti test:
test1
- server Apache
- script vbs1.html in <apache-DocumentRoot>
- richiedere l’URL http://localhost/vbs1.html con il browser IE
test2
- server PWS
- script vbs1.html in <pws-DocumentRoot>
- richiedere l'URL http://localhost/vbs1.html con il browser IE
2.6.2. Una pagina web con uno script JavaScript, lato browser
La pagina: js1.html
<html>
<head>
<title>essai 4 : une page web avec un script Javascript</title>
<script language="javascript">
function reagir(){
alert ("Vous avez cliqué sur le bouton OK");
}
</script>
</head>
<body>
<center>
<h1>Une page Web avec un script Javascript</h1>
<table>
<tr>
<td>Cliquez sur le bouton</td>
<td><input type="button" value="OK" name="cmdOK" onclick="reagir()"></td>
</tr>
</table>
</body>
</html>
Qui abbiamo qualcosa di identico alla pagina precedente, tranne per il fatto che abbiamo sostituito il linguaggio VBScript con il linguaggio JavaScript. Quest'ultimo presenta il vantaggio di essere supportato da entrambi i browser IE e Netscape. La sua esecuzione produce gli stessi risultati:

I test
test1
- server Apache
- script js1.html in <apache-DocumentRoot>
- richiedere l'URL http://localhost/js1.html con il browser IE o Netscape
test2
- server PWS
- script js1.html in <pws-DocumentRoot>
- richiedere l'URL http://localhost/js1.html con il browser IE o Netscape
2.7. Gli scambi client-server
Torniamo al nostro schema iniziale che illustrava gli attori di un'applicazione web:
![]() |
Qui ci interessano gli scambi tra il computer client e il computer server. Questi avvengono attraverso una rete ed è bene ricordare la struttura generale degli scambi tra due computer remoti.
2.7.1. Il modello OSI
Il modello di rete aperta denominato OSI (Open Systems Interconnection Reference Model), definito dall’ISO (International Standards Organisation), descrive una rete ideale in cui la comunicazione tra i computer può essere rappresentata da un modello a sette livelli:
![]() |
Ogni livello riceve servizi dal livello sottostante e fornisce i propri al livello superiore. Supponiamo che due applicazioni situate su macchine diverse, A e B, vogliano comunicare: lo fanno a livello del livello Application. Non hanno bisogno di conoscere tutti i dettagli del funzionamento della rete: ogni applicazione trasmette le informazioni che desidera inviare al livello sottostante, ovvero il livello Présentation. L’applicazione deve quindi conoscere solo le regole di interfaccia con il livello Présentation. Una volta che le informazioni si trovano nel livello Présentation, vengono trasferite secondo altre regole al livello Session e così via, fino a quando le informazioni non raggiungono il supporto fisico e vengono trasmesse fisicamente al computer di destinazione. A quel punto, subirà il processo inverso rispetto a quello a cui è stata sottoposta sul computer mittente.
Ad ogni livello, il processo mittente incaricato di inviare le informazioni le invia a un processo ricevente sull’altra macchina appartenente allo stesso livello. Lo fa secondo determinate regole che vengono definite protocollo di livello. Si ottiene quindi il seguente schema di comunicazione finale:
![]() |
Il ruolo dei diversi livelli è il seguente:
Garantisce la trasmissione dei bit su un supporto fisico. In questo livello si trovano apparecchiature terminali per l’elaborazione dei dati (E.T.T.D), quali terminali o computer, nonché apparecchiature di terminazione dei circuiti dati (E.T.C.D), quali modulatori/demodulatori, multiplexer e concentratori. I punti di interesse a questo livello sono: . la scelta della codifica delle informazioni (analogica o digitale) . la scelta della modalità di trasmissione (sincrona o asincrona). | |
Nasconde le caratteristiche fisiche del livello fisico. Rileva e corregge gli errori di trasmissione. | |
Gestisce il percorso che devono seguire le informazioni inviate sulla rete. Questo processo è denominato routage: determinare il percorso che un’informazione deve seguire per arrivare al destinatario. | |
Consente la comunicazione tra due applicazioni, mentre i livelli precedenti permettevano solo la comunicazione tra macchine. Un servizio fornito da questo livello può essere il multiplexing: il livello di trasporto potrà utilizzare una stessa connessione di rete (da macchina a macchina) per trasmettere informazioni appartenenti a più applicazioni. | |
In questo livello si trovano servizi che consentono a un’applicazione di aprire e mantenere una sessione di lavoro su una macchina remota. | |
Il suo scopo è uniformare la rappresentazione dei dati sulle diverse macchine. Pertanto, i dati provenienti da una macchina A saranno “formattati” dal livello Présentation della macchina A secondo un formato standard prima di essere inviati sulla rete. Una volta giunti al livello Présentation del computer destinatario B, che li riconoscerà grazie al loro formato standard, verranno rielaborati in modo diverso affinché l’applicazione del computer B possa riconoscerli. | |
A questo livello si trovano le applicazioni generalmente vicine all’utente, come la posta elettronica o il trasferimento di file. |
2.7.2. Il modello TCP/IP
Il modello OSI è un modello ideale. La suite di protocolli TCP/IP si avvicina ad esso nella forma seguente:
![]() |
- l'interfaccia di rete (la scheda di rete del computer) svolge le funzioni dei livelli 1 e 2 del modello OSI
- il livello IP (Internet Protocol) svolge le funzioni del livello 3 (rete)
- il livello TCP (Protocollo di controllo del trasferimento) o UDP (Protocollo datagramma utente) svolge le funzioni del livello 4 (trasporto). Il protocollo TCP garantisce che i pacchetti di dati scambiati tra i dispositivi arrivino correttamente a destinazione. In caso contrario, rinvia i pacchetti che si sono smarriti. Il protocollo UDP non svolge questa funzione e spetta quindi allo sviluppatore di applicazioni occuparsene. Ecco perché su Internet, che non è una rete affidabile al 100%, è il protocollo TCP quello più utilizzato. Si parla quindi di rete TCP-IP.
- Il livello Applicazione copre le funzioni dei livelli da 5 a 7 del modello OSI.
Le applicazioni web si trovano nel livello Application e si basano quindi sui protocolli TCP-IP. I livelli Application dei client e del server si scambiano messaggi che vengono affidati ai livelli da 1 a 4 del modello per essere instradati a destinazione. Per comunicare tra loro, i livelli applicativi delle due macchine devono «parlare» lo stesso linguaggio o protocollo. Quello delle applicazioni web si chiama HTTP (HyperText Transfer Protocol). Si tratta di un protocollo di tipo testuale, c.a.d, in cui i computer si scambiano righe di testo sulla rete per comunicare tra loro. Questi scambi sono standardizzati, c.a.d, in modo che il client disponga di una serie di messaggi per indicare esattamente ciò che desidera al server e che quest’ultimo disponga a sua volta di una serie di messaggi per fornire la risposta al client. Questo scambio di messaggi ha la seguente forma:
![]() |
Client --> Server
Quando il client invia la sua richiesta al server web, invia
- righe di testo nel formato HTTP per indicare ciò che desidera
- una riga vuota
- facoltativamente un documento
Server --> Client
Quando il server risponde al cliente, invia
- righe di testo nel formato HTTP per indicare ciò che sta inviando
- una riga vuota
- facoltativamente un documento
Gli scambi hanno quindi la stessa struttura in entrambe le direzioni. In entrambi i casi, può avvenire l’invio di un documento, anche se è raro che un client invii un documento al server. Ma il protocollo HTTP lo prevede. È ciò che consente, ad esempio, agli abbonati di un provider di scaricare vari documenti sul proprio sito personale ospitato presso tale provider. I documenti scambiati possono essere di qualsiasi tipo. Prendiamo ad esempio un browser che richiede una pagina web contenente immagini:
- il browser si connette al server web e richiede la pagina desiderata. Le risorse richieste sono identificate in modo univoco tramite URL (Uniform Resource Locator). Il browser invia solo intestazioni HTTP e nessun documento.
- Il server gli risponde. Innanzitutto invia delle intestazioni HTTP che indicano il tipo di risposta che sta inviando. Potrebbe trattarsi di un errore se la pagina richiesta non esiste. Se la pagina esiste, il server indicherà nelle intestazioni HTTP della sua risposta che, dopo di esse, invierà un documento HTML (HyperText Markup Language). Questo documento è costituito da una sequenza di righe di testo in formato HTML. Un testo HTML contiene tag (marcatori) che forniscono al browser indicazioni su come visualizzare il testo.
- Il client, in base alle intestazioni HTTP del server, sa che riceverà un documento HTML. Lo analizzerà e forse si accorgerà che contiene riferimenti a immagini. Queste ultime non sono presenti nel documento HTML. Effettua quindi una nuova richiesta allo stesso server web per richiedere la prima immagine di cui ha bisogno. Questa richiesta è identica a quella effettuata al punto 1, tranne per il fatto che la risorsa richiesta è diversa. Il server elaborerà questa richiesta inviando al cliente l’immagine richiesta. Questa volta, nella sua risposta, le intestazioni HTTP specificheranno che il documento inviato è un’immagine e non un documento HTML.
- Il client recupera l’immagine inviata. I passaggi 3 e 4 verranno ripetuti fino a quando il client (in genere un browser) non avrà tutti i documenti necessari per visualizzare l’intera pagina.
2.7.3. Il protocollo HTTP
Scopriamo il protocollo HTTP attraverso alcuni esempi. Cosa si scambiano un browser e un server web?
2.7.3.1. La risposta di un server HTTP
Scopriremo qui come un server web risponde alle richieste dei propri clienti. Il servizio web o servizio HTTP è un servizio TCP-IP che solitamente opera sulla porta 80. Potrebbe operare su un’altra porta. In tal caso, il browser client sarebbe tenuto a specificare tale porta nella richiesta che invia. Una richiesta ha la seguente forma generale:
con
protocollo | HTTP per il servizio web. Un browser può anche fungere da client per servizi FTP, news, Telnet, ecc. |
macchina | nome del computer su cui è in esecuzione il servizio web |
porta | porta del servizio web. Se è 80, è possibile omettere il numero della porta. È il caso più frequente |
percorso | percorso che indica la risorsa richiesta |
informazioni | informazioni aggiuntive fornite al server per specificare la richiesta del client |
Cosa fa un browser quando un utente richiede il caricamento di un URL?
- apre una comunicazione TCP-IP con la macchina e la porta indicate nella sezione machine[:port] del URL. Aprire una comunicazione TCP-IP significa creare un «canale» di comunicazione tra due macchine. Una volta creato questo canale, tutte le informazioni scambiate tra le due macchine passeranno attraverso di esso. La creazione di questo canale TCP-IP non implica ancora il protocollo Web HTTP.
- Una volta creato il canale TCP-IP, il client invierà la propria richiesta al server Web inviandogli righe di testo (comandi) nel formato HTTP. Invierà al server la parte relativa al percorso/alle informazioni del URL
- il server risponderà allo stesso modo e attraverso lo stesso canale
- uno dei due partner deciderà di chiudere il canale. Ciò dipende dal protocollo HTTP utilizzato. Con il protocollo HTTP 1.0, il server chiude la connessione dopo ciascuna delle sue risposte. Ciò obbliga un client che deve effettuare più richieste per ottenere i diversi documenti che costituiscono una pagina web ad aprire una nuova connessione per ogni richiesta, il che comporta un costo. Con il protocollo HTTP/1.1, il client può indicare al server di mantenere aperta la connessione fino a quando non gli chiederà di chiuderla. Può quindi recuperare tutti i documenti di una pagina web con un’unica connessione e chiuderla autonomamente una volta ottenuto l’ultimo documento. Il server rileverà tale chiusura e chiuderà a sua volta la connessione.
Per esaminare gli scambi tra un client e un server web, utilizzeremo un client generico TCP. Si tratta di un programma in grado di fungere da client per qualsiasi servizio dotato di un protocollo di comunicazione basato su righe di testo, come nel caso del protocollo HTTP. Queste righe di testo saranno digitate dall’utente tramite la tastiera. Ciò richiede che l’utente conosca il protocollo di comunicazione del servizio a cui intende accedere. La risposta del server viene quindi visualizzata sullo schermo. Il programma è stato scritto in Java e lo troverete in allegato. Qui lo utilizziamo in una finestra DOS su Windows e lo richiamiamo nel modo seguente:
con
machine | nome del computer su cui è in esecuzione il servizio da contattare |
porta | porta su cui viene fornito il servizio |
Con queste due informazioni, il programma aprirà una connessione TCP-IP con la macchina e la porta specificate. Questa connessione servirà per lo scambio di righe di testo tra il client e il server web. Le righe del client vengono digitate dall'utente tramite la tastiera e inviate al server. Le righe di testo restituite dal server come risposta vengono visualizzate sullo schermo. È quindi possibile instaurare un dialogo diretto tra l'utente alla tastiera e il server web. Proviamo con gli esempi già presentati. Avevamo creato la seguente pagina statica HTML:
<html>
<head>
<title>essai 1 : une page statique</title>
</head>
<body>
<center>
<h1>Une page statique...</h1>
</body>
</html>
che visualizziamo in un browser:

Si nota che l'URL richiesto è: http://localhost:81/essais/essai1.html. Il server del servizio web è quindi localhost (=server locale) e la porta è la 81. Se si richiede di visualizzare il testo HTML di questa pagina web (Visualizza/Sorgente), si ritrova il testo HTML creato inizialmente:

Ora utilizziamo il nostro client generico TCP per richiedere lo stesso URL:
Dos>java clientTCPgenerique localhost 81
Commandes :
GET /essais/essai1.html HTTP/1.0
<-- HTTP/1.1 200 OK
<-- Date: Mon, 08 Jul 2002 08:07:46 GMT
<-- Server: Apache/1.3.24 (Win32) PHP/4.2.0
<-- Last-Modified: Mon, 08 Jul 2002 08:00:30 GMT
<-- ETag: "0-a1-3d29469e"
<-- Accept-Ranges: bytes
<-- Content-Length: 161
<-- Connection: close
<-- Content-Type: text/html
<--
<-- <html>
<-- <head>
<-- <title>essai 1 : une page statique</title>
<-- </head>
<-- <body>
<-- <center>
<-- <h1>Une page statique...</h1>
<-- </body>
<-- </html>
All'avvio del client tramite il comando java clientTCPgenerique localhost 81, è stato creato un collegamento tra il programma e il server web in esecuzione sulla stessa macchina (localhost) e sulla porta 81. È ora possibile avviare gli scambi client-server nel formato HTTP. Si ricorda che questi sono costituiti da tre componenti:
- intestazioni HTTP
- riga vuota
- dati facoltativi
Nel nostro esempio, il client invia una sola richiesta:
GET /essais/essai1.html HTTP/1.0
Questa riga è composta da tre parti:
comando HTTP per richiedere una risorsa. Ne esistono altri: HEAD richiede una risorsa, limitandosi però alle intestazioni HTTP della risposta del server. La risorsa stessa non viene inviata. PUT consente al client di inviare un documento al server | |
risorsa richiesta | |
livello del protocollo HTTP utilizzato. In questo caso 1.0. Ciò significa che il server chiuderà la connessione non appena avrà inviato la sua risposta |
Le intestazioni HTTP devono sempre essere seguite da una riga vuota. È ciò che è stato fatto qui dal cliente. È così che il cliente o il server sa che la parte HTTP dello scambio è terminata. A questo punto, per il client è tutto finito. Non ha alcun documento da inviare. Inizia quindi la risposta del server, composta nel nostro esempio da tutte le righe che iniziano con il segno <--. Invia innanzitutto una serie di intestazioni HTTP seguite da una riga vuota:
<-- HTTP/1.1 200 OK
<-- Date: Mon, 08 Jul 2002 08:07:46 GMT
<-- Server: Apache/1.3.24 (Win32) PHP/4.2.0
<-- Last-Modified: Mon, 08 Jul 2002 08:00:30 GMT
<-- ETag: "0-a1-3d29469e"
<-- Accept-Ranges: bytes
<-- Content-Length: 161
<-- Connection: close
<-- Content-Type: text/html
<--
il server indica
| |
la data e l'ora della risposta | |
il server si identifica. In questo caso si tratta di un server Apache | |
data dell'ultima modifica della risorsa richiesta dal client | |
... | |
unità di misura dei dati inviati. In questo caso il byte | |
numero di byte del documento che verrà inviato dopo le intestazioni HTTP. Questo numero corrisponde in realtà alla dimensione in byte del file essai1.html: | |
il server comunica che chiuderà la connessione una volta inviato il documento | |
il server comunica che invierà del testo (text) nel formato HTML (html). |
Il client riceve queste intestazioni HTTP e ora sa che riceverà 161 byte che rappresentano un documento HTML. Il server invia questi 161 byte immediatamente dopo la riga vuota che segnalava la fine delle intestazioni HTTP:
<-- <html>
<-- <head>
<-- <title>essai 1 : une page statique</title>
<-- </head>
<-- <body>
<-- <center>
<-- <h1>Une page statique...</h1>
<-- </body>
<-- </html>
Qui si riconosce il file HTML creato inizialmente. Se il nostro client fosse un browser, dopo aver ricevuto queste righe di testo, le interpreterebbe per presentare all'utente, tramite la tastiera, la pagina seguente:

Utilizziamo nuovamente il nostro client generico TCP per richiedere la stessa risorsa, ma questa volta con il comando HEAD che richiede solo le intestazioni della risposta:
Dos>java.bat clientTCPgenerique localhost 81
Commandes :
HEAD /essais/essai1.html HTTP/1.1
Host: localhost:81
<-- HTTP/1.1 200 OK
<-- Date: Mon, 08 Jul 2002 09:07:25 GMT
<-- Server: Apache/1.3.24 (Win32) PHP/4.2.0
<-- Last-Modified: Mon, 08 Jul 2002 08:00:30 GMT
<-- ETag: "0-a1-3d29469e"
<-- Accept-Ranges: bytes
<-- Content-Length: 161
<-- Content-Type: text/html
<--
Otteniamo lo stesso risultato di prima senza il documento HTML. Si noti che nella sua richiesta HEAD, il cliente ha indicato di utilizzare il protocollo HTTP versione 1.1. Ciò lo obbliga a inviare una seconda intestazione HTTP specificando la coppia machine:port che il client intende interrogare: Host: localhost:81.
Ora richiediamo un'immagine sia con un browser che con il client generico TCP. Innanzitutto con un browser:

Il file univ01.gif ha 3167 byte:
Utilizziamo ora il client generico TCP:
E:\data\serge\JAVA\SOCKETS\client générique>java clientTCPgenerique localhost 81
Commandes :
HEAD /images/univ01.gif HTTP/1.1
host: localhost:81
<-- HTTP/1.1 200 OK
<-- Date: Tue, 09 Jul 2002 13:53:24 GMT
<-- Server: Apache/1.3.24 (Win32) PHP/4.2.0
<-- Last-Modified: Fri, 14 Apr 2000 11:37:42 GMT
<-- ETag: "0-c5f-38f70306"
<-- Accept-Ranges: bytes
<-- Content-Length: 3167
<-- Content-Type: image/gif
<--
Si notino i seguenti punti nella risposta del server:
| |
| |
|
2.7.3.2. La richiesta di un client HTTP
Ora poniamoci la seguente domanda: se vogliamo scrivere un programma che «comunichi» con un server web, quali comandi deve inviare al server web per ottenere una determinata risorsa? Negli esempi precedenti abbiamo ottenuto una prima risposta. Abbiamo incontrato tre comandi:
| |
| |
|
Esistono altri comandi. Per scoprirli, utilizzeremo ora un server generico TCP. Si tratta di un programma scritto in Java che troverete anch’esso in allegato. Si avvia con: java serveurTCPgenerique portEcoute, dove portEcoute è la porta a cui i client devono connettersi. Il programma serveurTCPgenerique
- visualizza sullo schermo i comandi inviati dai client
- invia loro in risposta le righe di testo digitate sulla tastiera da un utente. È quindi quest’ultimo a fungere da server. Nel nostro esempio, l’utente alla tastiera svolgerà il ruolo di un servizio web.
Simuliamo ora un server web avviando il nostro server generico sulla porta 88:
Dos> java serveurTCPgenerique 88
Serveur générique lancé sur le port 88
Apriamo ora un browser e richiediamo l’http://localhost:88/exemple.html URL. Il browser si connetterà quindi alla porta 88 del computer localhost e richiederà la pagina /exemple.html:

Osserviamo ora la finestra del nostro server che mostra ciò che il client gli ha inviato (alcune righe specifiche relative al funzionamento del programma serveurTCPgenerique sono state omesse per motivi di semplificazione):
Dos>java serveurTCPgenerique 88
Serveur générique lancé sur le port 88
...
<-- GET /exemple.html HTTP/1.1
<-- Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, */*
<-- Accept-Language: fr
<-- Accept-Encoding: gzip, deflate
<-- User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705; .NET CLR 1.0.2 914)
<-- Host: localhost:88
<-- Connection: Keep-Alive
<--
Le righe precedute dal segno <-- sono quelle inviate dal cliente. Si notano così delle intestazioni HTTP che non avevamo ancora incontrato:
| |
| |
| |
| |
|
Le intestazioni HTTP inviate dal browser terminano con una riga vuota, come previsto.
Elaboriamo una risposta per il nostro client. L’utente alla tastiera è qui il vero server e può elaborare una risposta manualmente. Ricordiamo la risposta fornita da un server Web in un esempio precedente:
<-- HTTP/1.1 200 OK
<-- Date: Mon, 08 Jul 2002 08:07:46 GMT
<-- Server: Apache/1.3.24 (Win32) PHP/4.2.0
<-- Last-Modified: Mon, 08 Jul 2002 08:00:30 GMT
<-- ETag: "0-a1-3d29469e"
<-- Accept-Ranges: bytes
<-- Content-Length: 161
<-- Connection: close
<-- Content-Type: text/html
<--
<-- <html>
<-- <head>
<-- <title>essai 1 : une page statique</title>
<-- </head>
<-- <body>
<-- <center>
<-- <h1>Une page statique...</h1>
<-- </body>
<-- </html>
Proviamo a scrivere manualmente (con la tastiera) una risposta analoga. Le righe che iniziano con --> : vengono inviate al client:
...
<-- Host: localhost:88
<-- Connection: Keep-Alive
<--
--> : HTTP/1.1 200 OK
--> : Server: serveur tcp generique
--> : Connection: close
--> : Content-Type: text/html
--> :
--> : <html>
--> : <head><title>Serveur generique</title></head>
--> : <body>
--> : <center>
--> : <h2>Reponse du serveur generique</h2>
--> : </center>
--> : </body>
--> : </html>
fin
Il comando fin è specifico per il funzionamento del programma serveurTCPgenerique. Interrompe l'esecuzione del programma e chiude la connessione tra il server e il client. Nella nostra risposta ci siamo limitati alle seguenti intestazioni HTTP:
HTTP/1.1 200 OK
--> : Server: serveur tcp generique
--> : Connection: close
--> : Content-Type: text/html
--> :
Non specifichiamo la dimensione del file che stiamo per inviare (Content-Length), ma ci limitiamo a indicare che chiuderemo la connessione (Connection: close) dopo averlo inviato. Questo è sufficiente per il browser. Quando rileva che la connessione è stata chiusa, il browser capirà che la risposta del server è terminata e visualizzerà la pagina HTML che gli è stata inviata. Quest’ultima è la seguente:
--> : <html>
--> : <head><title>Serveur generique</title></head>
--> : <body>
--> : <center>
--> : <h2>Reponse du serveur generique</h2>
--> : </center>
--> : </body>
--> : </html>
Il browser visualizza quindi la pagina seguente:

Se, come sopra, si esegue View/Source per vedere cosa ha ricevuto il browser, si ottiene:

ovvero esattamente ciò che è stato inviato dal server generico.
2.8. Il linguaggio HTML
Un browser Web può visualizzare vari documenti, il più comune dei quali è il documento HTML (HyperText Markup Language). Si tratta di un testo formattato con tag della forma <balise>texte</balise>. Pertanto, il testo <B>important</B> visualizzerà il testo importante in grassetto. Esistono tag singoli come il tag <hr> che visualizza una linea orizzontale. Non esamineremo i tag che si possono trovare in un testo HTML. Esistono numerosi software WYSIWYG che consentono di creare una pagina web senza scrivere una sola riga di codice HTML. Questi strumenti generano automaticamente il codice HTML di un layout realizzato con il mouse e controlli predefiniti. È quindi possibile inserire (con il mouse) una tabella nella pagina e poi consultare il codice HTML generato dal software per scoprire i tag da utilizzare per definire una tabella in una pagina web. Non è più complicato di così. Inoltre, la conoscenza del linguaggio HTML è indispensabile, poiché le applicazioni web dinamiche devono generare autonomamente il codice HTML da inviare ai client web. Questo codice viene generato dal programma e, ovviamente, è necessario sapere cosa generare affinché il client ottenga la pagina web desiderata.
In sintesi, non è affatto necessario conoscere l’intero linguaggio HTML per iniziare a programmare per il web. Tuttavia, tale conoscenza è necessaria e può essere acquisita utilizzando software WYSIWYG per la creazione di pagine web come Word, FrontPage, DreamWeaver e decine di altri. Un altro modo per scoprire le sottigliezze del linguaggio HTML è navigare sul web e visualizzare il codice sorgente delle pagine che presentano caratteristiche interessanti e ancora a voi sconosciute.
2.8.1. Un esempio
Consideriamo il seguente esempio, creato con FrontPage Express, uno strumento gratuito fornito con Internet Explorer. Il codice generato da FrontPage è stato qui semplificato. Questo esempio presenta alcuni elementi che si possono trovare in un documento web, quali:
- una tabella
- un'immagine
- un link

Un documento HTML ha la seguente struttura generale:
L'intero documento è racchiuso tra i tag <html>...</html>. È composto da due parti:
- <head>...</head>: è la parte non visibile del documento. Fornisce informazioni al browser che visualizzerà il documento. Spesso vi si trova il tag <title>...</title>, che definisce il testo che verrà visualizzato nella barra del titolo del browser. Vi si possono trovare anche altri tag, in particolare quelli che definiscono le parole chiave del documento, parole chiave che verranno poi utilizzate dai motori di ricerca. In questa parte si possono trovare anche degli script, scritti per lo più in JavaScript o VBScript, che verranno eseguiti dal browser.
- <body attributi>...</body>: è la parte che verrà visualizzata dal browser. I tag HTML contenuti in questa sezione indicano al browser l’aspetto visivo “desiderato” per il documento. Ogni browser interpreterà questi tag a modo suo. Due browser possono quindi visualizzare in modo diverso lo stesso documento web. Questo rappresenta solitamente uno dei grattacapi dei web designer.
Il codice HTML del nostro documento di esempio è il seguente:
<html>
<head>
<title>balises</title>
</head>
<body background="/images/standard.jpg">
<center>
<h1>Les balises HTML</h1>
<hr>
</center>
<table border="1">
<tr>
<td>cellule(1,1)</td>
<td valign="middle" align="center" width="150">cellule(1,2)</td>
<td>cellule(1,3)</td>
</tr>
<tr>
<td>cellule(2,1)</td>
<td>cellule(2,2)</td>
<td>cellule(2,3</td>
</tr>
</table>
<table border="0">
<tr>
<td>Une image</td>
<td><img border="0" src="/images/univ01.gif" width="80" height="95"></td>
</tr>
<tr>
<td>le site de l'ISTIA</td>
<td><a href="http://istia.univ-angers.fr">ici</a></td>
</tr>
</table>
</body>
</html>
Nel codice sono stati evidenziati solo i punti che ci interessano:
Elemento | tag ed esempi HTML |
<title>balises</title> balises apparirà nella barra del titolo del browser che visualizzerà il documento | |
<hr>: visualizza una linea orizzontale | |
<attributi tabella>....</table>: per definire la tabella <tr attributi>...</tr>: per definire una riga <td attributi>...</td>: per definire una cella esempi: <table border="1">...</table>: l'attributo border definisce lo spessore del bordo della tabella <td valign="middle" align="center" width="150">cella(1,2)</td>: definisce una cella il cui contenuto sarà cella(1,2). Questo contenuto sarà centrato verticalmente (valign="middle") e orizzontalmente (align="center"). La cella avrà una larghezza di 150 pixel (width="150") | |
<img border="0" src="/images/univ01.gif" width="80" height="95">: definisce un'immagine senza bordo (border="0"), alta 95 pixel (height="95"), larghezza di 80 pixel (width="80") e il cui file sorgente si trova in /images/univ01.gif sul server web (src="/images/univ01.gif"). Questo link si trova in un documento web ottenuto tramite il URL http://localhost:81/html/balises.htm. Pertanto, il browser richiederà il file URL http://localhost:81/images/univ01.gif per ottenere l'immagine qui indicata. | |
<a href="http://istia.univ-angers.fr">qui</a>: fa sì che il testo ici funga da link verso l'URL http://istia.univ-angers.fr. | |
<body background="/images/standard.jpg">: indica che l'immagine da utilizzare come sfondo della pagina si trova nel percorso URL /images/standard.jpg del server web. Nel contesto del nostro esempio, il browser richiederà l'URL http://localhost:81/images/standard.jpg per ottenere questa immagine di sfondo. |
Da questo semplice esempio si evince che, per costruire l’intero documento, il browser deve effettuare tre richieste al server:
- http://localhost:81/html/balises.htm per ottenere il codice sorgente HTML del documento
- http://localhost:81/images/univ01.gif per ottenere l’immagine univ01.gif
- http://localhost:81/images/standard.jpg per ottenere l'immagine di sfondo standard.jpg
L'esempio seguente mostra un modulo web creato anch'esso con FrontPage.

Il codice HTML generato da FrontPage e leggermente semplificato è il seguente:
<html>
<head>
<title>balises</title>
<script language="JavaScript">
function effacer(){
alert("Vous avez cliqué sur le bouton Effacer");
}//elimina
</script>
</head>
<body background="/images/standard.jpg">
<form method="POST" >
<table border="0">
<tr>
<td>Etes-vous marié(e)</td>
<td>
<input type="radio" value="Oui" name="R1">Oui
<input type="radio" name="R1" value="non" checked>Non
</td>
</tr>
<tr>
<td>Cases à cocher</td>
<td>
<input type="checkbox" name="C1" value="un">1
<input type="checkbox" name="C2" value="deux" checked>2
<input type="checkbox" name="C3" value="trois">3
</td>
</tr>
<tr>
<td>Champ de saisie</td>
<td>
<input type="text" name="txtSaisie" size="20" value="qqs mots">
</td>
</tr>
<tr>
<td>Mot de passe</td>
<td>
<input type="password" name="txtMdp" size="20" value="unMotDePasse">
</td>
</tr>
<tr>
<td>Boîte de saisie</td>
<td>
<textarea rows="2" name="areaSaisie" cols="20">
ligne1
ligne2
ligne3
</textarea>
</td>
</tr>
<tr>
<td>combo</td>
<td>
<select size="1" name="cmbValeurs">
<option>choix1</option>
<option selected>choix2</option>
<option>choix3</option>
</select>
</td>
</tr>
<tr>
<td>liste à choix simple</td>
<td>
<select size="3" name="lst1">
<option selected>liste1</option>
<option>liste2</option>
<option>liste3</option>
<option>liste4</option>
<option>liste5</option>
</select>
</td>
</tr>
<tr>
<td>liste à choix multiple</td>
<td>
<select size="3" name="lst2" multiple>
<option>liste1</option>
<option>liste2</option>
<option selected>liste3</option>
<option>liste4</option>
<option>liste5</option>
</select>
</td>
</tr>
<tr>
<td>bouton</td>
<td>
<input type="button" value="Effacer" name="cmdEffacer" onclick="effacer()">
</td>
</tr>
<tr>
<td>envoyer</td>
<td>
<input type="submit" value="Envoyer" name="cmdRenvoyer">
</td>
</tr>
<tr>
<td>rétablir</td>
<td>
<input type="reset" value="Rétablir" name="cmdRétablir">
</td>
</tr>
</table>
<input type="hidden" name="secret" value="uneValeur">
</form>
</body>
</html>
L'associazione tra controllo visivo <--> tag HTML è la seguente:
Controllo | tag HTML |
<form method="POST" > | |
<input type="text" name="txtSaisie" size="20" value="alcune parole"> | |
<input type="password" name="txtMdp" size="20" value="unMotDePasse"> | |
<textarea rows="2" name="areaSaisie" cols="20"> riga1 riga 2 riga3 </textarea> | |
<input type="radio" value="Sì" name="R1">Sì <input type="radio" name="R1" value="no" checked>No | |
<input type="checkbox" name="C1" value="uno">1 <input type="checkbox" name="C2" value="due" checked>2 <input type="checkbox" name="C3" value="tre">3 | |
<select size="1" name="cmbValeurs"> <option>opzione1</option> <option selected>opzione2</option> <option>opzione3</option> </select> | |
<select size="3" name="lst1"> <option selected>lista1</option> <option>lista2</option> <option>lista3</option> <option>lista4</option> <option>lista5</option> </select> | |
<select size="3" name="lst2" multiple> <option>lista1</option> <option>lista2</option> <option selected>lista3</option> <option>lista4</option> <option>lista5</option> </select> | |
<input type="submit" value="Invia" name="cmdRenvoyer"> | |
<input type="reset" value="Ripristina" name="cmdRétablir"> | |
<input type="button" value="Cancella" name="cmdEffacer" onclick="effacer()"> |
Esaminiamo questi diversi controlli.
2.8.1.1. Il modulo
<form method="POST" > |
<form name="..." method="..." action="...">...</form> | |
name="frmexemple": nome del modulo method="..." : metodo utilizzato dal browser per inviare al server web i valori raccolti nel modulo action="..." : URL a cui verranno inviati i valori raccolti nel modulo. Un modulo web è racchiuso tra i tag <form>...</form>. Il modulo può avere un nome (name="xx"). Questo vale per tutti i controlli presenti in un modulo. Tale nome è utile se il documento web contiene script che devono fare riferimento agli elementi del modulo. Lo scopo di un modulo è quello di raccogliere le informazioni fornite dall’utente tramite tastiera o mouse e di inviarle a una pagina web del server. Quale? Quella indicata nell’attributo action="URL". Se questo attributo è assente, le informazioni verranno inviate al server del documento in cui si trova il modulo. Questo sarebbe il caso nell’esempio sopra riportato. Finora abbiamo sempre considerato il client web come un soggetto che “richiede” informazioni a un server web, mai come un soggetto che “fornisce” informazioni. In che modo un client web riesce a fornire informazioni (quelle contenute nel modulo) a un server web? Ne parleremo in dettaglio più avanti. Può utilizzare due metodi diversi denominati POST e GET. L’attributo method="méthode", con il metodo impostato su GET o POST, del tag <form> indica al browser il metodo da utilizzare per inviare le informazioni raccolte nel modulo all'URL specificato dall'attributo action="URL". Quando l'attributo method non è specificato, viene utilizzato per impostazione predefinita il metodo GET. |
2.8.1.2. Campo di immissione
![]()
![]()
<input type="text" name="txtSaisie" size="20" value="alcune parole"> <input type="password" name="txtMdp" size="20" value="unMotDePasse"> |
<input type="..." name="..." size=".." value=".."> Il tag input è disponibile per diversi controlli. È l'attributo type che permette di distinguere questi diversi controlli tra loro. | |
type="text": specifica che si tratta di un campo di immissione type="password": i caratteri presenti nel campo di immissione vengono sostituiti da asterischi (*). È l'unica differenza rispetto al campo di immissione normale. Questo tipo di controllo è adatto per l'immissione delle password. size="20": numero di caratteri visibili nel campo - non impedisce l'inserimento di un numero maggiore di caratteri name="txtSaisie": nome del controllo value="alcune parole": testo che verrà visualizzato nel campo di immissione. |
2.8.1.3. Campo di immissione multilinea
![]()
<textarea rows="2" name="areaSaisie" cols="20"> ligne1 ligne2 ligne3 </textarea> |
<textarea ...>testo</textarea> visualizza un'area di immissione multilinea con del testo precompilato | |
rows="2": numero di righe cols="'20" : numero di colonne name="areaSaisie": nome del controllo |
2.8.1.4. Pulsanti di opzione
![]()
<input type="radio" value="Sì" name="R1">Sì <input type="radio" name="R1" value="no" checked>No |
<input type="radio" attributo2="valore2" ....>testo visualizza un pulsante di opzione con del testo accanto. | |
name="radio": nome del controllo. I pulsanti di opzione con lo stesso nome formano un gruppo di pulsanti che si escludono a vicenda: è possibile selezionare solo uno di essi. value="valore": valore assegnato al pulsante radio. Non bisogna confondere questo valore con il testo visualizzato accanto al pulsante radio. Quest'ultimo è destinato esclusivamente alla visualizzazione. checked: se questa parola chiave è presente, il pulsante radio è selezionato, altrimenti non lo è. |
2.8.1.5. Caselle di controllo
<input type="checkbox" name="C1" value="uno">1 <input type="checkbox" name="C2" value="due" checked>2 <input type="checkbox" name="C3" value="tre">3 |
![]()
<input type="checkbox" attributo2="valore2" ....>testo visualizza una casella di controllo con del testo accanto. | |
name="C1": nome del controllo. Le caselle di controllo possono avere o meno lo stesso nome. Le caselle con lo stesso nome formano un gruppo di caselle associate. value="valore": valore assegnato alla casella di controllo. Non bisogna confondere questo valore con il testo visualizzato accanto al pulsante di opzione. Quest'ultimo è destinato esclusivamente alla visualizzazione. checked: se questa parola chiave è presente, il pulsante di opzione è selezionato, altrimenti non lo è. |
2.8.1.6. Elenco a discesa (combo)
<select size="1" name="cmbValeurs"> <option>choix1</option> <option selected>scelta2</option> <option>choix3</option> </select> |
![]()
<select size=".." name=".."> <option [selected]>...</option> ... </select> visualizza in un elenco i testi compresi tra i tag <option>...</option> | |
name="cmbValeurs": nome del controllo. size="1": numero di elementi dell'elenco visibili. size="1" rende l'elenco equivalente a una casella combinata. selected: se questa parola chiave è presente per un elemento dell'elenco, quest'ultimo appare selezionato nell'elenco. Nel nostro esempio sopra riportato, l'elemento dell'elenco choix2 appare come elemento selezionato della casella combinata quando questa viene visualizzata per la prima volta. |
2.8.1.7. Elenco a selezione singola
<select size="3" name="lst1"> <option selected>lista1</option> <option>liste2</option> <option>liste3</option> <option>liste4</option> <option>liste5</option> </select> |

<select size=".." name=".."> <option [selected]>...</option> ... </select> visualizza in un elenco i testi compresi tra i tag <option>...</option> | |
gli stessi utilizzati per l'elenco a discesa che visualizza un solo elemento. Questo controllo differisce dall'elenco a discesa precedente solo per l'attributo size>1. |
2.8.1.8. Elenco a selezione multipla
<select size="3" name="lst2" multiple> <option selected>lista1</option> <option>liste2</option> <option selected>elenco3</option> <option>liste4</option> <option>liste5</option> </select> |

<select size=".." name=".." multiple> <option [selected]>...</option> ... </select> visualizza in un elenco i testi compresi tra i tag <option>...</option> | |
multiple: consente di selezionare più elementi dall'elenco. Nell'esempio sopra riportato, sono selezionati entrambi gli elementi liste1 e liste3. |
2.8.1.9. Pulsante di tipo button
<input type="button" value="Cancella" name="cmdEffacer" onclick="effacer()"> |
![]()
<input type="button" value="..." name="..." onclick="effacer()" ....> | |
type="button": definisce un controllo pulsante. Esistono altri due tipi di pulsante: submit e reset. value="Cancella": il testo visualizzato sul pulsante onclick="funzione()": consente di definire una funzione da eseguire quando l'utente fa clic sul pulsante. Questa funzione fa parte degli script definiti nel documento web visualizzato. La sintassi precedente è una sintassi javascript. Se gli script sono scritti in VBScript, occorre scrivere onclick="funzione" senza le parentesi. La sintassi rimane identica se è necessario passare dei parametri alla funzione: onclick="funzione(val1, val2,...)" Nel nostro esempio, un clic sul pulsante Effacer richiama la seguente funzione JavaScript effacer: La funzione effacer visualizza un messaggio: ![]() |
2.8.1.10. Pulsante di tipo «submit»
<input type="submit" value="Invia" name="cmdRenvoyer"> |
![]()
<input type="submit" value="Invia" name="cmdRenvoyer"> | |
type="submit": definisce il pulsante come pulsante di invio dei dati del modulo al server web. Quando l'utente clicca su questo pulsante, il browser invia i dati del modulo all'URL definito nell'attributo action del tag <form> secondo il metodo definito dall'attributo method dello stesso tag. value="Invia": il testo visualizzato sul pulsante |
2.8.1.11. Pulsante di tipo reset
<input type="reset" value="Ripristina" name="cmdRétablir"> |
![]()
<input type="reset" value="Ripristina" name="cmdRétablir"> | |
type="reset": definisce il pulsante come pulsante di ripristino del modulo. Quando l'utente fa clic su questo pulsante, il browser riporta il modulo allo stato in cui lo ha ricevuto. value="Ripristina": il testo visualizzato sul pulsante |
2.8.1.12. Campo nascosto
<input type="hidden" name="secret" value="uneValeur"> |
<input type="hidden" name="..." value="..."> | |
type="hidden": specifica che si tratta di un campo nascosto. Un campo nascosto fa parte del modulo ma non viene mostrato all'utente. Tuttavia, se l'utente richiedesse al proprio browser di visualizzare il codice sorgente, vedrebbe la presenza del tag <input type="hidden" value="..."> e quindi il valore del campo nascosto. value="unValore": valore del campo nascosto. A cosa serve il campo nascosto? Può consentire al server web di conservare le informazioni nel corso delle richieste di un cliente. Consideriamo un’applicazione per gli acquisti online. Il cliente acquista un primo articolo art1 in quantità q1 su una prima pagina del catalogo, quindi passa a una nuova pagina del catalogo. Per ricordare che il cliente ha acquistato q1 articoli art1, il server può inserire queste due informazioni in un campo nascosto del modulo web della nuova pagina. In questa nuova pagina, il cliente acquista gli articoli q2 e art2. Quando i dati di questo secondo modulo verranno inviati al server (submit), quest’ultimo riceverà non solo le informazioni (q2,art2), ma anche (q1,art1), che fa anch’esse parte del modulo come campi nascosti non modificabili dall’utente. Il server web inserirà quindi in un nuovo campo nascosto le informazioni (q1,art1) e (q2,art2) e invierà una nuova pagina del catalogo. E così via. |
2.8.2. Invio dei valori di un modulo a un server web da parte di un client web
Nella lezione precedente abbiamo visto che il client web dispone di due metodi per inviare a un server web i valori di un modulo che ha visualizzato: i metodi GET e POST. Vediamo con un esempio la differenza tra i due metodi. Riprendiamo l’esempio precedente e lo elaboriamo nel modo seguente:
- un browser richiede il modulo URL dell’esempio a un server web
- una volta ottenuto il modulo, lo compiliamo
- prima di inviare i valori del modulo al server web cliccando sul pulsante Envoyer di tipo submit, interrompiamo il server web e lo sostituiamo con il server generico TCP già utilizzato in precedenza. Ricordiamo che quest’ultimo visualizza sullo schermo le righe di testo che gli vengono inviate dal client web. In questo modo potremo vedere esattamente cosa invia il browser.
Il modulo viene compilato nel modo seguente:

Il codice URL utilizzato per questo documento è il seguente:

2.8.2.1. Metodo GET
Il documento HTML è configurato in modo che il browser utilizzi il metodo GET per inviare i valori del modulo al server web. Abbiamo quindi scritto:
Arrestiamo il server web e avviamo il nostro server generico TCP sulla porta 81:
E:\data\serge\JAVA\SOCKETS\serveur générique>java serveurTCPgenerique 81
Serveur générique lancé sur le port 81
Ora torniamo al nostro browser per inviare i dati del modulo al server web utilizzando il pulsante Envoyer:

Ecco quindi cosa riceve il server generico TCP:
<-- GET /html/balises.htm?R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecret&area
Saisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&
cmdRenvoyer=Envoyer&secret=uneValeur HTTP/1.1
<-- Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd
.ms-powerpoint, application/vnd.ms-excel, */*
<-- Referer: http://localhost:81/html/balises.htm
<-- Accept-Language: fr
<-- Accept-Encoding: gzip, deflate
<-- User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705)
<-- Host: localhost:81
<-- Connection: Keep-Alive
<--
Tutto è contenuto nella prima intestazione HTTP inviata dal browser:
<-- GET /html/balises.htm?R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecret&area
Saisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&
cmdRenvoyer=Envoyer&secret=uneValeur HTTP/1.1
Si nota che è molto più complesso di quanto si fosse visto finora. Vi si ritrova la sintassi GET URL HTTP/1.1, ma in una forma particolare: GET URL?param1=valore1¶m2=valore2&... HTTP/1.1 dove parami sono i nomi dei controlli del modulo web e «valori» i valori ad essi associati. Esaminiamoli più da vicino. Di seguito presentiamo una tabella a tre colonne:
- colonna 1: riporta la definizione di un controllo HTML dell’esempio
- colonna 2: mostra come viene visualizzato questo controllo in un browser
- colonna 3: riporta il valore inviato al server dal browser per il controllo della colonna 1 nella forma in cui appare nella richiesta GET dell'esempio
controllo HTML | visualizzazione | valore/i restituito/i |
<input type="radio" value="Sì" name="R1">Sì <input type="radio" name="R1" value="no" checked>No | - il valore dell'attributo value del pulsante di opzione selezionato dall'utente. | |
<input type="checkbox" name="C1" value="uno">1 <input type="checkbox" name="C2" value="due" checked>2 <input type="checkbox" name="C3" value="tre">3 | C1=uno C2=due - valori degli attributi value delle caselle selezionate dall'utente | |
<input type="text" name="txtSaisie" size="20" value="alcune parole"> | txtInserimento=programmazione+web - testo digitato dall'utente nel campo di immissione. Gli spazi sono stati sostituiti dal segno + | |
<input type="password" name="txtMdp" size="20" value="unMotDePasse"> | txtMdp=questoèsegreto - testo digitato dall'utente nel campo di immissione | |
<textarea rows="2" name="areaSaisie" cols="20"> riga1 riga 2 riga3 </textarea> | areaInserimento=le+basi+della%0D%0A programmazione+web - testo digitato dall'utente nel campo di immissione. %OD%OA è il marcatore di fine riga. Gli spazi sono stati sostituiti dal segno + | |
<select size="1" name="cmbValeurs"> <option>scelta1</option> <option selected>scelta2</option> <option>scelta3</option> </select> | cmbValori=scelta3 - valore selezionato dall'utente nell'elenco a selezione singola | |
<select size="3" name="lst1"> <option selected>lista1</option> <option>lista2</option> <option>lista3</option> <option>lista4</option> <option>lista5</option> </select> | ![]() | lst1=lista3 - valore scelto dall'utente nell'elenco a selezione singola |
<select size="3" name="lst2" multiple> <option selected>lista1</option> <option>lista2</option> <option selected>lista3</option> <option>lista4</option> <option>lista5</option> </select> | ![]() | lst2=lista1 lst2=lista3 - valori selezionati dall'utente nell'elenco a selezione multipla |
<input type="submit" value="Invia" name="cmdRenvoyer"> | cmdRenvoyer=Invia - nome e attributo value del pulsante utilizzato per inviare i dati del modulo al server | |
<input type="hidden" name="secret" value="uneValeur"> | secret=unValore - attributo value del campo nascosto |
Ripetiamo la stessa operazione, ma questa volta lasciando che sia il server web a elaborare la risposta, e vediamo quale sarà il risultato. La pagina restituita dal server web è la seguente:

È esattamente la stessa ricevuta inizialmente prima della compilazione del modulo. Per capire il motivo, occorre esaminare nuovamente l’attributo URL richiesto dal browser quando l’utente preme il pulsante Envoyer:
<-- GET /html/balises.htm?R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecret&area
Saisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&
cmdRenvoyer=Envoyer&secret=uneValeur HTTP/1.1
La pagina richiesta è /html/balises.htm. Inoltre, a questa pagina vengono passati i valori del modulo. Per il momento, la pagina /html/balises.htm, che è una pagina statica, non utilizza questi valori. Pertanto, la precedente GET è equivalente a
ed è per questo che il server ci ha rinviato nuovamente la pagina iniziale. Si noti che il browser visualizza correttamente l’URL completo che è stato richiesto:

2.8.2.2. Metodo POST
Il documento HTML è configurato in modo che il browser utilizzi ora il metodo POST per inviare i valori del modulo al server web:
Arrestiamo il server web e avviamo il server generico TCP (già visto in precedenza ma leggermente modificato per l’occasione) sulla porta 81:
E:\data\serge\JAVA\SOCKETS\serveur générique>java serveurTCPgenerique2 81
Serveur générique lancé sur le port 81
Ora torniamo al nostro browser per inviare i dati del modulo al server web utilizzando il pulsante Invia:

Ecco quindi cosa riceve il server generico TCP:
<-- POST /html/balises.htm HTTP/1.1
<-- Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd
.ms-powerpoint, application/vnd.ms-excel, */*
<-- Referer: http://localhost:81/html/balises.htm
<-- Accept-Language: fr
<-- Content-Type: application/x-www-form-urlencoded
<-- Accept-Encoding: gzip, deflate
<-- User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705)
<-- Host: localhost:81
<-- Content-Length: 210
<-- Connection: Keep-Alive
<-- Cache-Control: no-cache
<--
<-- R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecret&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&cmdRenvoyer=Envoyer&secret=uneValeur
Rispetto a quanto già noto, si notano i seguenti cambiamenti nella richiesta del browser:
- L'intestazione iniziale HTTP non è più GET, bensì POST. La sintassi è POST URL HTTP/1.1, dove URL è l'intestazione richiesta dal browser. Allo stesso tempo, POST indica che il browser ha dei dati da trasmettere al server.
- La riga Content-Type: application/x-www-form-urlencoded indica quale tipo di dati invierà il browser. Si tratta di dati di modulo (x-www-form) codificati (urlencoded). Questa codifica fa sì che alcuni caratteri dei dati trasmessi vengano trasformati per evitare errori di interpretazione da parte del server. Pertanto, lo spazio viene sostituito da +, il carattere di fine riga da %OD%OA,... In generale, tutti i caratteri contenuti nei dati che potrebbero essere interpretati erroneamente dal server (&, +, %, ...) vengono trasformati in %XX, dove XX è il loro codice esadecimale.
- La riga Content-Length: 210 indica al server quanti caratteri il client gli invierà una volta terminate le intestazioni HTTP, c.a.d, dopo la riga vuota che segnala la fine delle intestazioni.
- I dati (210 caratteri): R1=Sì&C1=uno&C2=due&txtSaisie=programmazione+web&txtMdp=questoèsegreto&areaSaisie=le+basi+della%0D%0Aprogrammazione+web&cmbValeurs=scelta3&lst1=lista3&lst2=lista1&lst2=lista3&cmdRenvoyer=Invia&segreto=uneValeur
Si nota che i dati trasmessi da POST hanno lo stesso formato di quelli trasmessi da GET.
Esiste un metodo migliore dell’altro? Abbiamo visto che se i valori di un modulo venivano inviati dal browser con il metodo GET, il browser visualizzava nel proprio campo Adresse il URL richiesto nella forma URL?param1=val1¶m2=val2&.... Questo può essere visto come un vantaggio o uno svantaggio:
- un vantaggio se si vuole consentire all’utente di inserire questo URL configurato tra i propri link preferiti
- uno svantaggio se non si desidera che l’utente abbia accesso a determinate informazioni del modulo, come ad esempio i campi nascosti
D'ora in poi, utilizzeremo quasi esclusivamente il metodo POST nei nostri moduli.
2.8.2.3. Recupero dei valori da un modulo web
Una pagina statica richiesta da un client che invia inoltre dei parametri tramite POST o GET non può in alcun modo recuperarli. Solo un programma può farlo ed è proprio il programma che si occuperà quindi di generare una risposta al client, una risposta che sarà dinamica e generalmente dipendente dai parametri ricevuti. Questo è il campo della programmazione web, argomento che tratteremo più in dettaglio nel capitolo seguente con la presentazione delle tecnologie Java per la programmazione web: i servlet e le pagine JSP.









