2. Nozioni di base
In questo capitolo presentiamo le nozioni di base della programmazione web. Il suo obiettivo principale è quello di introdurre i principi chiave della programmazione web prima di metterli in pratica con un linguaggio e un ambiente specifici. Include numerosi esempi che vi invitiamo a provare per "prendere confidenza" gradualmente con la filosofia dello sviluppo web.
2.1. : Componenti di un'applicazione web

Numero | Ruolo | Esempi comuni |
Sistema operativo server | Linux, Windows | |
Server Web | Apache (Linux, Windows) IIS (NT), PWS (Win9x) | |
Script 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 sulla stessa macchina del il programma che lo utilizza oppure su un'altra macchina tramite Internet. | Oracle (Linux, Windows) MySQL (Linux, Windows) Access (Windows) SQL Server (Windows) | |
Sistema operativo client | Linux, Windows | |
Browser web | Netscape, Internet Explorer | |
Script eseguiti sul lato client all'interno del browser. Questi script non hanno accesso ai dischi del computer client. | VBScript (IE) JavaScript (IE, Netscape) PerlScript (IE) Applet Java |
2.2. Gli scambi di dati in un'applicazione web con un modulo

Macchina clientServer
Numero | Ruolo |
Il browser richiede un URL per la prima volta (http://machine/url). Non vengono passati parametri. | |
Il server web invia la pagina web corrispondente a quell'URL. Può essere statica o generata dinamicamente da uno script lato server (SA) che potrebbe aver utilizzato contenuti provenienti da database (SB, SC). In questo caso, lo script rileverà che l'URL è stato richiesto senza alcun parametro e genererà la pagina web iniziale. Il browser riceve la pagina e la visualizza (CA). Gli script lato browser (CB) potrebbero aver modificato la pagina iniziale inviata dal server. Quindi, attraverso le interazioni tra l'utente (CD) e gli script (CB), la pagina web verrà modificata. In particolare, verranno compilati i moduli. | |
L'utente invia i dati del modulo, che devono quindi essere inviati al server web. Il browser richiede l'URL iniziale o un altro, a seconda dei casi, e contemporaneamente trasmette i valori del modulo al server. A tal fine può utilizzare due metodi: GET e POST. Una volta ricevuta la richiesta del client, il server attiva lo script (SA) associato all'URL richiesto, che rileverà i parametri e li elaborerà. | |
Il server fornisce la pagina web generata dal programma (SA, SB, SC). Questo passaggio è identico al precedente passaggio 2. La comunicazione procede ora secondo i passaggi 2 e 3. |
2.3. Risorse utili su
Di seguito è riportato un elenco di risorse per l'installazione e l'utilizzo di alcuni strumenti per lo sviluppo web. Un'appendice fornisce le istruzioni di installazione per questi strumenti.
http://www.apache.org - Apache: Installazione e implementazione, O'Reilly | |
http://www.microsoft.com | |
http://www.activestate.com - Programmazione in Perl, Larry Wall, O'Reilly - Applicazioni CGI in Perl, Neuss e Vromans, O'Reilly - la documentazione HTML inclusa in Active Perl | |
http://www.php.net - Programmazione Web con PHP, Lacroix, Eyrolles - Manuale utente PHP disponibile sul sito web di PHP | |
http://msdn.microsoft.com/scripting/vbscript/download/vbsdoc.exe http://msdn.microsoft.com/scripting/default.htm?/scripting/vbscript - Interfaccia tra il Web e i database in ambiente WinNT, Alex Homer, Eyrolles | |
http://msdn.microsoft.com/scripting/jscript/download/jsdoc.exe http://developer.netscape.com/docs/manuals/index.html | |
http://developer.netscape.com/docs/manuals/index.html | |
http://www.sun.com - JAVA Servlets, Jason Hunter, O'Reilly - Programmazione di rete con Java, Elliotte Rusty Harold, O'Reilly - JDBC e Java, George Reese, O'Reilly | |
http://www.mysql.com http://www.oracle.com - Il manuale di MySQL è disponibile sul sito web di MySQL - Oracle 8i su Linux, Gilles Briard, Eyrolles - Oracle 8i su NT, Gilles Briard, Eyrolles |
2.4. Note
Di seguito, daremo per scontato che siano stati installati una serie di strumenti e useremo la seguente notazione:
notazione | significato |
radice dell'albero delle directory del server Apache | |
Directory principale delle pagine web servite da Apache. Le pagine web devono trovarsi all'interno di questa directory principale. Pertanto, l'URL http://localhost/page1.htm corrisponde al file <apache-DocumentRoot>\page1.htm. | |
radice dell'albero di directory associato all'alias cgi-bin, dove possono essere collocati 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 servite da PWS. Le pagine web devono trovarsi sotto questa radice. Pertanto, l'URL http://localhost/page1.htm corrisponde al file <pws-DocumentRoot>\page1.htm. | |
Radice dell'albero di directory di Perl. L'eseguibile perl.exe si trova solitamente in <perl>\bin. | |
La radice dell'albero di directory PHP. Il file eseguibile php.exe si trova solitamente nella directory <php>. | |
Radice dell'albero di directory Java. I file eseguibili Java si trovano in <java>\bin. | |
Radice del server Tomcat. Esempi di servlet sono disponibili in <tomcat>\webapps\examples\servlets ed esempi di pagine JSP in <tomcat>\webapps\examples\jsp |
Per ciascuno di questi strumenti, consultare l'appendice, che fornisce le istruzioni di 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 questa sezione, proponiamo vari test utilizzando diversi server web e linguaggi di programmazione per dimostrare l'universalità del concetto di web.
2.5.1. Pagina HTML statica (HyperText Markup Language)
Si consideri 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

-
Avvia il server Apache
-
Posizionare lo script essai1.html in <apache-DocumentRoot>
-
Visualizzare l'URL http://localhost/essai1.html in un browser
-
Arresta il server Apache
-
Avvia il server PWS
-
Inserisci lo script essai1.html in <pws-DocumentRoot>
-
Visualizza l'URL http://localhost/essai1.html in 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
-
Avvia il server PWS
-
Inserire lo script essai2.asp in <pws-DocumentRoot>
-
Richiedere l'URL http://localhost/essai2.asp utilizzando 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. Potrebbe essere necessario modificarlo se necessario. Una volta eseguito da un server web, lo script produce la seguente pagina:

Il test
-
Server web: Apache
-
Per riferimento, visualizza il file di configurazione srm.conf o httpd.conf (a seconda della tua versione di Apache) in <apache>\confs e cerca la riga che menziona cgi-bin per determinare la directory <apache-cgi-bin> in cui dovresti collocare essai3.pl.
-
Posizionare lo script essai3.pl in <apache-cgi-bin>
-
Richiedere l'URL http://localhost/cgi-bin/essai3.pl
Si noti che il caricamento della pagina Perl richiede più tempo rispetto a quello della 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. Esso non rimane in memoria in modo permanente.
2.5.4. Uno script PHP (Personal Home Page)
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:
Test


-
controlla il file di configurazione srm.conf o httpd.conf di Apache in <Apache>\confs
-
Per riferimento, controllare le righe di configurazione PHP
-
Avvia il server Apache
-
Posizionare essai4.php in <apache-DocumentRoot>
-
Richiedere l'URL http://localhost/essai4.php
-
Avvia il server PWS
-
Per riferimento, controllare la configurazione di PWS relativa a PHP
-
Inserire essai4.php in <pws-DocumentRoot>\php
-
Richiedi l'URL http://localhost/essai4.php
2.5.5. Uno script JSP
Lo script heure.jsp
<% //programme Java affichant l'heure %>
<%@ page import="java.util.*" %>
<%
// code JAVA pour calculer l'heure
Calendar calendrier=Calendar.getInstance();
int heures=calendrier.get(Calendar.HOUR_OF_DAY);
int minutes=calendrier.get(Calendar.MINUTE);
int secondes=calendrier.get(Calendar.SECOND);
// heures, minutes, secondes sont des variables globales
// qui pourront être utilisées dans le code HTML
%>
<% // code 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 produce la seguente pagina:

Test
- Posizionare lo script heure.jsp in <tomcat>\jakarta-tomcat\webapps\examples\jsp (Tomcat 3.x) o in <tomcat>\webapps\examples\jsp (Tomcat 4.x)
- Avvia il server Tomcat
- Richiedere l'URL http://localhost:8080/examples/jsp/heure.jsp
2.5.6. Conclusione
Gli esempi precedenti hanno dimostrato che:
- una pagina HTML può essere generata dinamicamente da un programma. Questo è il punto centrale della programmazione web.
- i linguaggi e i server web utilizzati possono variare. 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 combina il server IIS con un linguaggio .NET (C#, VB.NET, ecc.)
- La tecnologia Java Servlet e le pagine JSP in esecuzione su vari server (Tomcat, Apache, IIS) e su varie piattaforme (Windows, Linux). È proprio quest'ultima tecnologia che verrà discussa in modo più approfondito in questo documento.
2.6. Script lato browser
Una pagina HTML può contenere script che vengono eseguiti dal browser. Esistono molti linguaggi di scripting lato browser. Eccone alcuni:
Linguaggio | Browser supportati |
VBScript | IE |
JavaScript | IE, Netscape |
PerlScript | IE |
Java | IE, Netscape |
Vediamo alcuni esempi.
2.6.1. Una pagina web con uno script VBScript, sul lato del 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 contiene non solo codice HTML, ma anche un programma destinato ad essere eseguito dal browser che carica 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> e </script> vengono utilizzati per delimitare gli script all'interno di una pagina HTML. Questi script possono essere scritti in vari linguaggi e l'attributo language del tag <script> specifica il linguaggio utilizzato. In questo caso, si tratta di VBScript. Non entreremo nei dettagli di questo linguaggio. Lo script sopra riportato definisce una funzione chiamata react che visualizza un messaggio. Quando viene chiamata questa funzione? La seguente riga di codice HTML ce lo dice:
L'attributo onclick specifica il nome della funzione da chiamare quando l'utente clicca sul pulsante OK. Una volta che il browser ha caricato questa pagina e l'utente clicca sul pulsante OK, apparirà la seguente pagina:

Test
Solo Internet Explorer è in grado di eseguire script VBScript. Netscape richiede dei componenti aggiuntivi per farlo. Possiamo eseguire i seguenti test:
-
Server Apache
-
Script vbs1.html in <apache-DocumentRoot>
-
Richiedere l'URL http://localhost/vbs1.html utilizzando Internet Explorer
-
Server PWS
-
Script vbs1.html in <pws-DocumentRoot>
-
Richiedere l'URL http://localhost/vbs1.html utilizzando Internet Explorer
2.6.2. Una pagina web con uno script JavaScript, sul 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>
Questa pagina è identica alla precedente, tranne per il fatto che abbiamo sostituito VBScript con JavaScript. JavaScript ha il vantaggio di essere supportato sia da Internet Explorer che da Netscape. Eseguendolo si ottengono gli stessi risultati:

I test
-
Server Apache
-
Script js1.html in <apache-DocumentRoot>
-
Richiedere l'URL http://localhost/js1.html utilizzando Internet Explorer o Netscape
-
Server PWS
-
Script js1.html in <pws-DocumentRoot>
-
Richiedere l'URL http://localhost/js1.html utilizzando Internet Explorer o Netscape
2.7. Comunicazione client-server
Torniamo al nostro diagramma iniziale che illustra i componenti di un'applicazione web:
![]() |
Qui ci concentriamo sugli scambi tra il computer client e il computer server. Questi avvengono su una rete, ed è utile rivedere la struttura generale degli scambi tra due computer remoti.
2.7.1. Il modello OSI
Il modello di rete aperto noto come OSI (Open Systems Interconnection Reference Model), definito dall'ISO (International Organization for Standardization), 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 servizi al livello sovrastante. Supponiamo che due applicazioni situate su macchine diverse A e B vogliano comunicare: lo fanno a livello di Applicazione. Non hanno bisogno di conoscere tutti i dettagli di come funziona la rete: ogni applicazione passa le informazioni che desidera trasmettere al livello sottostante: il livello di Presentazione. L'applicazione deve quindi conoscere solo le regole di interfaccia con il livello di Presentazione. Una volta che le informazioni si trovano nel livello di Presentazione, vengono passate secondo altre regole al livello di Sessione, e così via, fino a quando le informazioni raggiungono il mezzo fisico e vengono trasmesse fisicamente alla macchina di destinazione. Lì, subiranno il processo inverso di quello che hanno subito sulla macchina mittente.
A ogni livello, il processo mittente responsabile dell'invio delle informazioni le invia a un processo ricevente sull'altra macchina appartenente allo stesso livello. Lo fa secondo determinate regole note come protocollo di livello. Abbiamo quindi il seguente diagramma di comunicazione finale:
![]() |
I ruoli dei diversi livelli sono i seguenti:
Garantisce la trasmissione di bit su un mezzo fisico. Questo livello include apparecchiature terminali di elaborazione dati (DPTE) quali terminali o computer, nonché apparecchiature di terminazione del circuito dati (DCTE) quali modulatori/demodulatori, multiplexer e concentratori. I punti chiave 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 le informazioni inviate sulla rete devono seguire. Questo processo è chiamato routing: determinare il percorso che le informazioni devono seguire per raggiungere la loro destinazione. | |
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 può utilizzare una singola connessione di rete (da macchina a macchina) per trasmettere dati appartenenti a più applicazioni. | |
Questo livello fornisce servizi che consentono a un'applicazione di aprire e mantenere una sessione di lavoro su una macchina remota. | |
Il suo scopo è quello di standardizzare la rappresentazione dei dati tra macchine diverse. Pertanto, i dati provenienti dalla macchina A saranno "formattati" dal livello di presentazione della macchina A secondo un formato standard prima di essere inviati in rete. Una volta raggiunto il livello di presentazione della macchina di destinazione B, che li riconoscerà grazie al loro formato standard, saranno riformattati in modo che l'applicazione sulla macchina B possa riconoscerli. | |
A questo livello si trovano le applicazioni che sono 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 lo approssima nel modo 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 (Transmission Control Protocol) o UDP (User Datagram Protocol) svolge le funzioni del livello 4 (trasporto). Il protocollo TCP garantisce che i pacchetti di dati scambiati tra le macchine raggiungano la loro destinazione. In caso contrario, invia nuovamente i pacchetti persi. Il protocollo UDP non svolge questo compito, quindi spetta allo sviluppatore dell'applicazione farlo. Questo è il motivo per cui, su Internet — che non è una rete affidabile al 100% — il protocollo TCP è il più utilizzato. Si parla in questo caso di rete TCP-IP.
- Il livello Applicazione copre le funzioni dei livelli da 5 a 7 del modello OSI.
Le applicazioni web risiedono nel livello Applicazione e quindi si basano sui protocolli TCP/IP. I livelli Applicazione delle macchine client e server scambiano messaggi, che vengono poi trasferiti ai livelli da 1 a 4 del modello per essere instradati verso la loro destinazione. Per comunicare tra loro, i livelli Applicazione di entrambe le macchine devono "parlare" la stessa lingua o lo stesso protocollo. Il protocollo utilizzato dalle applicazioni web si chiama HTTP (HyperText Transfer Protocol). Si tratta di un protocollo basato su testo, il che significa che le macchine scambiano righe di testo attraverso la rete per comunicare. Questi scambi sono standardizzati, il che significa che il client dispone di una serie di messaggi per comunicare al server esattamente ciò che desidera, e anche il server dispone di una serie di messaggi per fornire al client la propria risposta. Questo scambio di messaggi assume la seguente forma:
![]() |
Client --> Server
Quando il client effettua una richiesta al server web, invia
- righe di testo in formato HTTP per indicare ciò che desidera
- una riga vuota
- facoltativamente un documento
Server --> Client
Quando il server risponde al client, invia
- righe di testo in formato HTTP per indicare ciò che sta inviando
- una riga vuota
- facoltativamente un documento
Le comunicazioni seguono quindi lo stesso formato in entrambe le direzioni. In entrambi i casi, è possibile inviare un documento, anche se è raro che un client invii un documento al server. Ma il protocollo HTTP lo consente. Questo è ciò che permette, ad esempio, agli abbonati di un ISP di caricare vari documenti sul proprio sito web personale ospitato da quell'ISP. I documenti scambiati possono essere di qualsiasi tipo. Consideriamo 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 dagli URL (Uniform Resource Locators). Il browser invia solo le intestazioni HTTP e nessun documento.
- Il server risponde. Innanzitutto invia le intestazioni HTTP indicando 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 invierà un documento HTML (HyperText Markup Language) a seguire. Questo documento è una sequenza di righe di testo in formato HTML. Il testo HTML contiene tag (indicatori) che forniscono al browser le istruzioni su come visualizzare il testo.
- Il client sa dalle intestazioni HTTP del server che riceverà un documento HTML. Analizzerà questo documento e potrebbe notare che contiene riferimenti a immagini. Queste immagini non sono incluse 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 l'immagine richiesta al client. 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 (di solito un browser) non avrà tutti i documenti necessari per visualizzare l'intera pagina.
2.7.3. Il protocollo HTTP
Esploriamo il protocollo HTTP attraverso alcuni esempi. Cosa si scambiano un browser e un server web?
2.7.3.1. La risposta da un server HTTP
Qui vedremo come un server web risponde alle richieste dei suoi client. Il servizio web o servizio HTTP è un servizio TCP/IP che di solito opera sulla porta 80. Potrebbe operare su una porta diversa. In quel caso, il browser client dovrebbe specificare quella porta nell'URL che richiede. Un URL segue generalmente questo formato:
protocollo://macchina[:porta]/percorso/info
dove
protocollo | http per il servizio web. Un browser può anche fungere da client per FTP, news, Telnet e altri servizi. |
macchina | nome della macchina che ospita il servizio web |
porta | Porta del servizio web. Se è 80, il numero di porta può essere omesso. Questo è il caso più comune |
percorso | percorso della risorsa richiesta |
info | informazioni aggiuntive fornite al server per specificare la richiesta del client |
Cosa fa un browser quando un utente richiede il caricamento di un URL?
- Stabilisce una connessione TCP/IP con la macchina e la porta specificate nella parte machine[:port] dell’URL. Stabilire una connessione TCP/IP significa creare un “canale” di comunicazione tra due macchine. Una volta stabilito questo canale, tutte le informazioni scambiate tra le due macchine passeranno attraverso di esso. La creazione di questo canale TCP/IP non coinvolge ancora il protocollo HTTP del Web.
- Una volta stabilita la connessione TCP/IP, il client invia la sua richiesta al server web inviando righe di testo (comandi) in formato HTTP. Invia la parte path/info dell'URL al server
- Il server risponderà allo stesso modo e attraverso la stessa connessione
- Una delle due parti deciderà di chiudere la connessione. Ciò dipende dal protocollo HTTP utilizzato. Con HTTP 1.0, il server chiude la connessione dopo ciascuna delle sue risposte. Ciò costringe un client che deve effettuare più richieste per recuperare i vari documenti che compongono 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 dirà di chiuderla. Può quindi recuperare tutti i documenti di una pagina web utilizzando un'unica connessione e chiudere la connessione una volta ottenuto l'ultimo documento. Il server rileverà questa chiusura e chiuderà a sua volta la connessione.
Per esaminare gli scambi tra un client e un server web, useremo un client TCP generico. Si tratta di un programma in grado di fungere da client per qualsiasi servizio che utilizzi un protocollo di comunicazione testuale, come il 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 sta tentando di accedere. La risposta del server viene quindi visualizzata sullo schermo. Il programma è stato scritto in Java ed è disponibile in appendice. Qui lo utilizziamo in una finestra DOS in Windows e lo chiamiamo come segue:
java clientTCPgenerique macchina porta
con
macchina | nome della macchina 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 verso la macchina e la porta specificate. Questa connessione verrà utilizzata per scambiare righe di testo tra il client e il server web. Le righe del client vengono digitate dall'utente sulla 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 HTML statica:
<html>
<head>
<title>essai 1 : une page statique</title>
</head>
<body>
<center>
<h1>Une page statique...</h1>
</body>
</html>
che visualizziamo in un browser:

Possiamo vedere che l'URL richiesto è: http://localhost:81/essais/essai1.html. Il server web è quindi localhost (=macchina locale) sulla porta 81. Se visualizziamo il codice sorgente HTML di questa pagina web (Visualizza/Sorgente), vediamo il testo HTML che era stato originariamente creato:

Ora utilizziamo il nostro client TCP generico 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>
Quando il client viene avviato utilizzando il comando java clientTCPgenerique localhost 81, viene stabilita una connessione tra il programma e il server web in esecuzione sulla stessa macchina (localhost) sulla porta 81. La comunicazione client-server in formato HTTP può ora avere inizio. Ricordiamo che queste richieste hanno tre componenti:
- intestazioni HTTP
- riga vuota
- dati opzionali
Nel nostro esempio, il client invia una sola richiesta:
GET /tests/test1.html HTTP/1.0
Questa riga è composta da tre parti:
Comando HTTP per richiedere una risorsa. Ne esistono altri: HEAD richiede una risorsa ma si limita alle intestazioni HTTP nella risposta del server. La risorsa stessa non viene inviata. PUT consente al client di inviare un documento al server | |
risorsa richiesta | |
Versione del protocollo HTTP utilizzata. 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. Questo è ciò che il client ha fatto qui. È così che il client o il server sanno che la parte HTTP dello scambio è completa. Qui, il client ha terminato. Non ha alcun documento da inviare. Inizia quindi la risposta del server, costituita nel nostro esempio da tutte le righe che iniziano con il simbolo <--. Invia prima 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 dice
| |
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 nel documento da inviare dopo le intestazioni HTTP. Questo numero corrisponde in realtà alla dimensione in byte del file essai1.html: | |
Il server indica che chiuderà la connessione una volta inviato il documento | |
Il server indica che invierà del testo (text) in 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 ha segnato 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 riconosciamo il file HTML che era stato inizialmente costruito. Se il nostro client fosse un browser, dopo aver ricevuto queste righe di testo, le interpreterebbe per visualizzare la seguente pagina all'utente:

Utilizziamo nuovamente il nostro client TCP generico 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 client ha indicato che stava utilizzando la versione 1.1 di HTTP. Ciò richiede l'invio di un secondo header HTTP che specifichi la coppia macchina:porta che il client desidera interrogare: Host: localhost:81.
Ora richiediamo un'immagine utilizzando sia un browser che il client TCP generico. Per prima cosa, utilizzando un browser:

Il file univ01.gif è di 3167 byte:
Ora utilizziamo il client TCP generico:
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. 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? Abbiamo già iniziato a rispondere a questa domanda negli esempi precedenti. Abbiamo incontrato tre comandi:
| |
| |
|
Esistono altri comandi. Per scoprirli, useremo ora un server TCP generico. Si tratta di un programma scritto in Java, che troverete anche in appendice. Si avvia con il comando: java genericTCPserver listeningPort, dove listeningPort è la porta a cui i client devono connettersi. Il programma genericTCPserver
- visualizza sullo schermo i comandi inviati dai client
- invia loro, in risposta, le righe di testo digitate sulla tastiera da un utente. È quindi l’utente a fungere da server. Nel nostro esempio, l’utente alla tastiera svolgerà il ruolo di un servizio web
Ora simuliamo un server web avviando il nostro server generico sulla porta 88:
Dos> java serveurTCPgenerique 88
Serveur générique lancé sur le port 88
Ora apriamo un browser e inseriamo l'URL http://localhost:88/exemple.html. Il browser si connetterà quindi alla porta 88 sul computer localhost e richiederà la pagina /example.html:

Ora diamo un'occhiata alla finestra del nostro server, che mostra ciò che il client gli ha inviato (alcune righe specifiche relative al funzionamento del programma serverTCPgenerique sono state omesse per semplicità):
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 simbolo <-- sono quelle inviate dal client. Questo rivela le intestazioni HTTP che non abbiamo ancora incontrato:
| |
| |
| |
| |
|
Le intestazioni HTTP inviate dal browser terminano con una riga vuota, come previsto.
Creiamo una risposta per il nostro client. L'utente alla tastiera è il vero e proprio server in questo caso e può creare una risposta manualmente. Ricordiamo la risposta inviata 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 creare manualmente (con la tastiera) una risposta simile. 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 end è specifico per il funzionamento del programma serverTCPgenerique. 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 inviando (Content-Length), ma indichiamo semplicemente che chiuderemo la connessione (Connection: close) dopo averlo inviato. Questo è sufficiente per il browser. Quando vedrà che la connessione è stata chiusa, capirà che la risposta del server è completa e visualizzerà la pagina HTML che gli è stata inviata. La pagina è 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 seguente pagina:

Se clicchi su Visualizza/Sorgente qui sopra per vedere cosa ha ricevuto il browser, otterrai:

cioè esattamente ciò che è stato inviato dal server generico.
2.8. HTML
Un browser web può visualizzare vari tipi di documenti, i più comuni dei quali sono i documenti HTML (HyperText Markup Language). Questi consistono in testo formattato con tag della forma <tag>testo</tag>. Pertanto, il testo <B>importante</B> visualizzerà la parola "importante" in grassetto. Esistono tag autonomi come il tag <hr>, che visualizza una linea orizzontale. Non esamineremo tutti i tag che si possono trovare nel testo HTML. Esistono molti programmi software WYSIWYG che consentono di creare una pagina web senza scrivere una sola riga di codice HTML. Questi strumenti generano automaticamente il codice HTML per un layout creato utilizzando il mouse e controlli predefiniti. È quindi possibile inserire (utilizzando il mouse) una tabella nella pagina e quindi visualizzare il codice HTML generato dal software per scoprire i tag da utilizzare per definire una tabella su una pagina web. Non è più complicato di così. Inoltre, la conoscenza dell'HTML è essenziale poiché le applicazioni web dinamiche devono generare autonomamente il codice HTML da inviare ai client web. Questo codice viene generato a livello di programmazione e, ovviamente, è necessario sapere cosa generare affinché il client riceva la pagina web desiderata.
Per riassumere, non è necessario conoscere l'intero linguaggio HTML per iniziare a programmare per il web. Tuttavia, questa conoscenza è necessaria e può essere acquisita attraverso l'uso di editor di pagine web WYSIWYG come Word, FrontPage, DreamWeaver e decine di altri. Un altro modo per scoprire le complessità dell'HTML è navigare sul web e visualizzare il codice sorgente delle pagine che presentano elementi interessanti che non avete mai incontrato prima.
2.8.1. Un esempio
Si consideri il seguente esempio, creato con FrontPage Express, uno strumento gratuito incluso in Internet Explorer. Il codice generato da FrontPage è stato semplificato in questa sede. Questo esempio presenta alcuni elementi comunemente presenti in un documento web, quali:
- una tabella
- un'immagine
- un link

Un documento HTML ha generalmente la seguente struttura:
L'intero documento è racchiuso tra i tag <html>...</html>. È composto da due parti:
- <head>...</head>: questa è la parte non visualizzabile del documento. Fornisce informazioni al browser che visualizzerà il documento. Spesso contiene i tag <title>...</title>, che impostano il testo che apparirà nella barra del titolo del browser. Può contenere anche altri tag, in particolare quelli che definiscono le parole chiave del documento, che vengono poi utilizzate dai motori di ricerca. Questa sezione può contenere anche script, solitamente scritti in JavaScript o VBScript, che verranno eseguiti dal browser.
- <attributi body>...</body>: Questa è la sezione che verrà visualizzata dal browser. I tag HTML contenuti in questa sezione indicano al browser il layout visivo "desiderato" per il documento. Ogni browser interpreta questi tag a modo suo. Di conseguenza, due browser possono visualizzare lo stesso documento web in modo diverso. Questa è generalmente una delle sfide che devono affrontare i web designer.
Il codice HTML per il 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 di nostro interesse:
Tag HTML | e esempi HTML |
I tag <title></title> I tag appariranno nella barra del titolo del browser quando il documento viene visualizzato | |
<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">cell(1,2)</td>: definisce una cella il cui contenuto sarà cell(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"), larga 80 pixel (width="80") e il cui file sorgente è /images/univ01.gif sul server web (src="/images/univ01.gif"). Questo collegamento si trova in un documento web accessibile tramite l'URL http://localhost:81/html/balises.htm. Pertanto, il browser richiederà l'URL http://localhost:81/images/univ01.gif per recuperare l'immagine a cui si fa riferimento qui. | |
<a href="http://istia.univ-angers.fr">qui</a>: fa sì che il testo "qui" funga da collegamento all'URL http://istia.univ-angers.fr. | |
<body background="/images/standard.jpg">: indica che l'immagine da utilizzare come sfondo della pagina si trova all'URL /images/standard.jpg sul server web. Nel contesto del nostro esempio, il browser richiederà l'URL http://localhost:81/images/standard.jpg per recuperare questa immagine di sfondo. |
In questo semplice esempio possiamo vedere che, per costruire l'intero documento, il browser deve effettuare tre richieste al server:
- http://localhost:81/html/balises.htm per recuperare il codice sorgente HTML del documento
- http://localhost:81/images/univ01.gif per recuperare l'immagine univ01.gif
- http://localhost:81/images/standard.jpg per recuperare 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 ripulito è il seguente:
<html>
<head>
<title>balises</title>
<script language="JavaScript">
function effacer(){
alert("Vous avez cliqué sur le bouton Effacer");
}//effacer
</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 visiva tra <--> e il tag HTML è la seguente:
Visivo | Tag HTML |
<form method="POST" > | |
<input type="text" name="txtInput" size="20" value="alcune parole"> | |
<input type="password" name="txtPassword" size="20" value="aPassword"> | |
<textarea rows="2" name="inputArea" cols="20"> riga1 riga2 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="cmbValues"> <option>opzione1</option> <option selected>opzione2</option> <option>opzione3</option> </select> | |
<select size="3" name="lst1"> <option selected>list1</option> <option>elenco2</option> <option>elenco3</option> <option>elenco4</option> <option>elenco5</option> </select> | |
<select size="3" name="lst2" multiple> <option>list1</option> <option>list2</option> <opzione selezionata>list3</option> <option>elenco4</option> <option>elenco5</option> </select> | |
<input type="submit" value="Invia" name="cmdSubmit"> | |
<input type="reset" value="Reimposta" name="cmdReset"> | |
<input type="button" value="Cancella" name="cmdClear" onclick="clear()"> |
Esaminiamo questi diversi controlli.
2.8.1.1. Il
<form method="POST" > |
<form name="..." method="..." action="...">...</form> | |
name="exampleform": nome del modulo method="..." : metodo utilizzato dal browser per inviare i valori raccolti nel modulo al server web 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"). Ciò vale per tutti i controlli presenti all'interno di un modulo. Questo 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 inserite dall'utente tramite la tastiera o il mouse e inviarle a un URL del server web. Quale? Quello a cui fa riferimento l'attributo action="URL". Se questo attributo manca, le informazioni saranno inviate all'URL del documento in cui si trova il modulo. Questo sarebbe il caso dell'esempio sopra riportato. Finora abbiamo sempre considerato il client web come un soggetto che "richiede" informazioni da un server web, mai come un soggetto che "fornisce" informazioni ad esso. In che modo un client web fornisce informazioni (i dati contenuti nel modulo) a un server web? Torneremo su questo argomento in dettaglio più avanti. Può utilizzare due metodi diversi chiamati POST e GET. L'attributo method="method", dove method è GET o POST, del tag <form> indica al browser quale metodo 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="txtInput" size="20" value="alcune parole"> <input type="password" name="txtMdp" size="20" value="aPassword"> |
<input type="..." name="..." size=".." value=".."> Il tag input esiste per vari controlli. È l'attributo type che distingue questi diversi controlli l'uno dall'altro. | |
type="text": specifica che si tratta di un campo di immissione testo type="password": i caratteri nel campo di immissione vengono sostituiti da asterischi (*). Questa è l’unica differenza rispetto a un normale campo di immissione. Questo tipo di controllo è adatto per l’immissione di password. size="20": numero di caratteri visibili nel campo — non impedisce l’inserimento di più caratteri name="txtInput": 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"> riga1 riga2 riga3 </textarea> |
<textarea ...>testo</textarea> visualizza un campo di immissione testo multilinea con del testo già all'interno | |
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" attribute2="value2" ....>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 mutuamente esclusivo: è possibile selezionarne solo uno. value="value": valore assegnato al pulsante di opzione. Non confondere questo valore con il testo visualizzato accanto al pulsante di opzione. Il testo serve solo a scopo di visualizzazione. checked: se questa parola chiave è presente, il pulsante di opzione è selezionato; in caso contrario, 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" attribute2="value2" ....>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 di controllo con lo stesso nome formano un gruppo di caselle correlate. value="value": il valore assegnato alla casella di controllo. Non confondere questo valore con il testo visualizzato accanto al pulsante di opzione. Il testo serve solo a scopo di 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="cmbValues"> <option>scelta1</option> <option selected>scelta2</option> <option>opzione3</option> </select> |
![]()
<select size=".." name=".."> <option [selected]>...</option> ... </select> visualizza il testo tra i tag <option>...</option> in un elenco | |
name="cmbValeurs": nome del controllo. size="1": numero di voci visibili dell'elenco. size="1" rende l'elenco equivalente a una casella combinata. selected: se questa parola chiave è presente per una voce dell'elenco, tale voce appare selezionata nell'elenco. Nel nostro esempio sopra, la voce dell'elenco choice2 appare come voce selezionata nella casella combinata quando viene visualizzata per la prima volta. |
2.8.1.7. Elenco a selezione singola
<select size="3" name="lst1"> <option selected>list1</option> <option>list2</option> <option>elenco3</option> <option>elenco4</option> <option>elenco5</option> </select> |

<select size=".." name=".."> <option [selected]>...</option> ... </select> visualizza il testo tra i tag <option>...</option> in un elenco | |
gli stessi dell'elenco a discesa che visualizza un solo elemento. Questo controllo differisce dal precedente elenco a discesa solo per l'attributo size>1. |
2.8.1.8. Elenco a selezione multipla
<select size="3" name="lst2" multiple> <option selected>list1</option> <option>list2</option> <option selected>elenco3</option> <option>elenco4</option> <option>list5</option> </select> |

<select size=".." name=".." multiple> <option [selected]>...</option> ... </select> visualizza il testo tra i tag <option>...</option> in un elenco | |
multiple: consente di selezionare più elementi dall'elenco. Nell'esempio sopra, gli elementi list1 e list3 sono entrambi selezionati. |
2.8.1.9. Pulsante
<input type="button" value="Cancella" name="cmdClear" onclick="clear()"> |
![]()
<input type="button" value="..." name="..." onclick="clear()" ....> | |
type="button": definisce un controllo pulsante. Esistono altri due tipi di pulsanti: submit e reset. value="Clear": il testo visualizzato sul pulsante onclick="function()": 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 sopra riportata è sintassi JavaScript. Se gli script sono scritti in VBScript, si scriverebbe onclick="function" senza le parentesi. La sintassi rimane la stessa se è necessario passare dei parametri alla funzione: onclick="function(val1, val2,...)" Nel nostro esempio, cliccando sul pulsante Cancella viene chiamata la seguente funzione JavaScript clear: La funzione clear visualizza un messaggio: ![]() |
2.8.1.10. Pulsante Invia
<input type="submit" value="Invia" name="cmdSend"> |
![]()
<input type="submit" value="Invia" name="cmdRenvoyer"> | |
type="submit": definisce il pulsante come pulsante per l'invio dei dati del modulo al server web. Quando l'utente fa clic su questo pulsante, il browser invierà i dati del modulo all'URL definito nell'attributo action del tag <form>, utilizzando il metodo definito dall'attributo method dello stesso tag. value="Invia": il testo visualizzato sul pulsante |
2.8.1.11. Pulsante Reset
<input type="reset" value="Reimposta" name="cmdReset"> |
![]()
<input type="reset" value="Reset" name="cmdReset"> | |
type="reset": definisce il pulsante come pulsante di reset del modulo. Quando l'utente clicca su questo pulsante, il browser ripristinerà il modulo allo stato in cui è stato ricevuto. value="Reset": il testo visualizzato sul pulsante |
2.8.1.12. Campo nascosto
<input type="hidden" name="secret" value="aValue"> |
<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 visualizzato all'utente. Tuttavia, se l'utente chiedesse 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="aValue": valore del campo nascosto. Qual è lo scopo di un campo nascosto? Consente al server web di conservare le informazioni tra le richieste di un client. Si consideri un'applicazione di shopping online. Il cliente acquista un primo articolo art1 in quantità q1 sulla prima pagina di un catalogo e poi passa a una nuova pagina del catalogo. Per ricordare che il cliente ha acquistato q1 articoli di art1, il server può inserire queste due informazioni in un campo nascosto nel modulo web sulla nuova pagina. In questa nuova pagina, il cliente acquista q2 articoli di art2. Quando i dati di questo secondo modulo vengono inviati al server, il server non solo riceverà le informazioni (q2,art2) ma anche (q1,art1), che fa anch'esse parte del modulo come campo nascosto che non può essere modificato dall'utente. Il server web inserirà quindi le informazioni (q1, art1) e (q2, art2) in un nuovo campo nascosto e invierà una nuova pagina del catalogo. E così via. |
2.8.2. Invio dei valori del modulo a un server web da parte di un client web
Nella lezione precedente abbiamo accennato al fatto che il client web dispone di due metodi per inviare i valori di un modulo visualizzato a un server web: i metodi GET e POST. Vediamo un esempio per comprendere la differenza tra i due metodi. Riprendiamo l’esempio precedente e gestiamolo come segue:
- Un browser richiede l'URL dell'esempio da un server web
- Una volta ottenuto il modulo, lo compiliamo
- Prima di inviare i valori del modulo al server web cliccando sul pulsante "Invia", fermiamo il server web e lo sostituiamo con il server TCP generico utilizzato in precedenza. Ricordiamo che questo server visualizza sullo schermo le righe di testo che gli vengono inviate dal client web. In questo modo, vedremo esattamente ciò che il browser sta inviando.
Il modulo viene compilato come segue:

L'URL utilizzato per questo documento è il seguente:

2.8.2.1. Metodo GET
Il documento HTML è programmato in modo tale 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 TCP generico 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 Invia:

Ecco cosa riceve il server TCP generico:
<-- 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 nel primo header HTTP inviato 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
Possiamo notare che si tratta di un caso molto più complesso rispetto a quelli che abbiamo incontrato finora. Utilizza la sintassi URL GET HTTP/1.1, ma in un formato specifico: GET URL?param1=value1¶m2=value2&... HTTP/1.1, dove i parametri sono i nomi dei controlli del modulo web e i valori sono quelli ad essi associati. Diamo un'occhiata più da vicino. Di seguito è riportata una tabella a tre colonne:
- Colonna 1: mostra la definizione di un controllo HTML dall'esempio
- Colonna 2: mostra come questo controllo appare in un browser
- Colonna 3: mostra il valore inviato al server dal browser per il controllo nella Colonna 1, nella forma che assume nella richiesta GET dell'esempio
Controllo HTML | Valore | valore/i restituito/i |
<input type="radio" value="Sì" name="R1">Sì <input type="radio" name="R1" value="no" checked>No | R1=Sì - il valore dell'attributo value del pulsante di opzione selezionato dall'utente. | |
<input type="checkbox" name="C1" value="one">1 <input type="checkbox" name="C2" value="due" checked>2 <input type="checkbox" name="C3" value="three">3 | C1=uno C2=due - valori degli attributi value delle caselle di controllo selezionate dall'utente | |
<input type="text" name="txtInput" size="20" value="alcune parole"> | txtInput=web+programmazione - testo digitato dall'utente nel campo di immissione. Gli spazi sono stati sostituiti dal segno + | |
<input type="password" name="txtMdp" size="20" value="aPassword"> | txtPassword=thisIsSecret - testo inserito dall'utente nel campo di immissione | |
<textarea rows="2" name="areaSaisie" cols="20"> riga1 riga2 riga3 </textarea> | campo_input=le+basi+del+web%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> | cmbValues=option3 - valore selezionato dall'utente dall'elenco a selezione singola | |
<select size="3" name="lst1"> <option selected>list1</option> <option>list2</option> <option>elenco3</option> <option>elenco4</option> <option>elenco5</option> </select> | ![]() | lst1=list3 - valore selezionato dall'utente dall'elenco a selezione singola |
<select size="3" name="lst2" multiple> <option selected>list1</option> <option>list2</option> <option selected>list3</option> <option>list4</option> <option>list5</option> </select> | ![]() | lst2=list1 lst2=list3 - valori selezionati dall'utente dall'elenco a selezione multipla |
<input type="submit" value="Invia" name="cmdSubmit"> | cmdSubmit=Invia - attributi name e value del pulsante utilizzato per inviare i dati del modulo al server | |
<input type="hidden" name="secret" value="aValue"> | secret=aValue - attributo value del campo nascosto |
Ripetiamo la stessa operazione, ma questa volta lasciamo che sia il server web a generare la risposta e vediamo di cosa si tratta. La pagina restituita dal server web è la seguente:

È esattamente la stessa ricevuta inizialmente prima che il modulo venisse compilato. Per capire il motivo, dobbiamo esaminare nuovamente l'URL richiesto dal browser quando l'utente fa clic sul pulsante Invia:
<-- 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
L'URL richiesto è /html/tags.htm. Passiamo anche i valori del modulo a questo URL. Per ora, l'URL /html/tags.htm, che è una pagina statica, non utilizza questi valori. Pertanto, la precedente richiesta GET è equivalente a
ed è per questo che il server ci ha inviato nuovamente la pagina iniziale. Si noti che il browser visualizza l'URL completo che è stato richiesto:

2.8.2.2. Metodo POST
Il documento HTML è programmato in modo tale 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 TCP generico (che abbiamo già visto in precedenza, ma che abbiamo leggermente modificato per questo scopo) 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 cosa riceve il server TCP generico:
<-- 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à sappiamo, notiamo i seguenti cambiamenti nella richiesta del browser:
- L'intestazione HTTP iniziale non è più GET ma POST. La sintassi è POST HTTP/1.1 URL, dove URL è l'URL richiesto dal browser. Allo stesso tempo, POST significa che il browser ha dei dati da inviare al server.
- La riga Content-Type: application/x-www-form-urlencoded indica il tipo di dati che il browser invierà. Si tratta di dati di modulo (x-www-form) codificati tramite URL. Questa codifica fa sì che alcuni caratteri nei dati trasmessi vengano trasformati per impedire al server di interpretarli erroneamente. Pertanto, lo spazio viene sostituito da +, l'interruzione di riga da %OD%OA e così via. In generale, tutti i caratteri contenuti nei dati che potrebbero essere interpretati erroneamente dal server (&, +, %, ecc.) vengono convertiti in %XX, dove XX è il loro codice esadecimale.
- La riga Content-Length: 210 indica al server quanti caratteri il client invierà una volta completate le intestazioni HTTP, ovvero dopo la riga vuota che segnala la fine delle intestazioni.
- I dati (210 caratteri): R1=Yes&C1=one&C2=two&txtInput=web+programming&txtPassword=thisissecret&areaInput=the+basics+of+web%0D%0Aweb+programming&cmbValues=choice3&lst1=list3&lst2=list1&lst2=list3&cmdSubmit=Submit&secret=aValue
Si noti che i dati inviati tramite POST hanno lo stesso formato dei dati inviati tramite GET.
Un metodo è migliore dell'altro? Abbiamo visto che se i valori di un modulo fossero inviati dal browser utilizzando il metodo GET, il browser visualizzerebbe l'URL richiesto nella barra degli indirizzi nel formato URL?param1=val1¶m2=val2&.... Questo può essere visto sia come un vantaggio che come uno svantaggio:
- un vantaggio se si desidera consentire all'utente di salvare questo URL parametrizzato nei propri segnalibri
- uno svantaggio se non si desidera che l'utente abbia accesso a determinate informazioni del modulo, come i campi nascosti
D'ora in poi, useremo 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 anche parametri tramite POST o GET non può recuperarli in alcun modo. Solo un programma può farlo, ed è il programma che genererà poi una risposta al client: una risposta che sarà dinamica e generalmente basata sui parametri ricevuti. Questo è il regno della programmazione web, un argomento che tratteremo più dettagliatamente nel prossimo capitolo con un'introduzione alle tecnologie di programmazione web Java: servlet e pagine JSP.







