La comunicazione sul Web e il protocollo HTTP
Dietro ogni click c'è una telefonata tra client e server. Entriamo dentro la telefonata: metodi, header, codici di stato e dove finiscono i parametri.
1. Introduzione
Ho preferito partire da un’analogia semplice, perché il funzionamento di HTTP si capisce meglio raccontandolo prima che formalizzandolo: ogni volta che apri una pagina web, dietro le quinte accade qualcosa di molto simile a una telefonata. Qualcuno compone il numero (il client), qualcun altro risponde e fornisce ciò che gli viene chiesto (il server). In questa lezione entriamo dentro quella “telefonata”: vedremo come è fatta una richiesta HTTP, come le risponde un server, quali metodi esistono per chiedere, inviare, modificare o cancellare dati, e come si interpreta l’esito di una comunicazione attraverso i codici di stato.
Ragazzi, se capite la telefonata avete capito HTTP. Il client compone (apre TCP su porta 80), dice "Vorrei /index.html" (richiesta GET), il server risponde "Ok, eccolo, 200 OK" oppure "Non ce l'ho, 404". Poi riaggancia (chiude connessione) o resta in linea (connessione persistente). Tenete a mente questa scena per tutta la lezione, vi salverà all'orale.
2. Obiettivi
- Comprendere il modello client-server e i ruoli distinti che client e server assumono nella comunicazione Web
- Conoscere il protocollo HTTP, la struttura dei suoi messaggi (richiesta e risposta) e la differenza tra connessioni non persistenti e persistenti
- Saper distinguere i metodi HTTP (GET, POST, PUT, DELETE) e sapere dove ciascuno colloca i propri parametri
- Interpretare i codici di stato HTTP e comprendere il ruolo della codifica URL nel trasporto dei dati
3. Il modello client-server e la comunicazione sul Web
Alla base del funzionamento del Web troviamo il modello client-server, un’architettura in cui due entità svolgono ruoli ben distinti: il client richiede un servizio, il server lo fornisce. Questa separazione dei compiti consente di realizzare sistemi scalabili, affidabili e facilmente manutenibili — lo stesso modello che abbiamo incontrato nella prima lezione del modulo, qui applicato al caso specifico del Web.
Pensate a YouTube: un solo video di 10 minuti viene visto da 10 milioni di persone. Se fosse peer-to-peer puro, ogni utente dovrebbe inviare il video agli altri. Con client-server, il server ha il video e lo serve a tutti, posso aggiungere 100 server dietro un load balancer e gestire 100 milioni di utenti senza riscrivere l'app. È questo il motivo per cui tutte le Web App usano questo modello.
3.1 Il ruolo del Client
Il client è il soggetto attivo: prende l’iniziativa e avvia una richiesta verso un server remoto. Nel contesto del Web, il client è tipicamente un browser (Chrome, Firefox…) oppure un’applicazione che utilizza il protocollo HTTP per accedere a risorse online. Quando digiti un indirizzo o clicchi un link, il client costruisce una richiesta HTTP specificando l’URL della risorsa, l’indirizzo del server e la porta del servizio — generalmente la 80 per HTTP o la 443 per HTTPS — poi resta in attesa della risposta, che può contenere una pagina HTML, un file multimediale o dati strutturati come JSON o XML.
Quando digitate www.esempio.it il browser non fa una sola cosa: fa la risoluzione DNS, apre TCP sulla 443, fa il TLS handshake, poi invia la richiesta GET. Se all'orale vi chiedono "Cosa succede quando digito un URL?", elencate tutti i passaggi, non solo GET. È una domanda classica da 10.
3.2 Il ruolo del Server
Il server svolge un ruolo complementare e passivo: resta costantemente in ascolto su una specifica porta TCP, pronto a ricevere richieste. Software come Apache, Nginx o IIS gestiscono questo compito, analizzando le richieste ricevute e fornendo le risposte appropriate — che possono contenere la risorsa richiesta oppure un codice di errore, come il noto 404 Not Found.
In laboratorio con Docker useremo Apache con PHP, ma sappiate che Nginx è più veloce a servire file statici e gestisce meglio 10.000 connessioni contemporanee. Molte aziende usano Nginx come front-end che smista le richieste ad Apache dietro. Per ora vi basta sapere che entrambi fanno la stessa cosa: ascoltano su porta 80 e rispondono a GET.
4. Il protocollo HTTP
Il protocollo HTTP (HyperText Transfer Protocol) è il fondamento della comunicazione sul Web: un protocollo di livello applicativo che permette lo scambio di risorse tra client e server sfruttando TCP come mezzo di trasporto. Il Web, in fondo, nasce dalla combinazione di tre elementi: HTML per la struttura delle pagine, URL per l’indirizzamento delle risorse e HTTP per la comunicazione vera e propria.
Una comunicazione HTTP inizia sempre con l’apertura di una connessione TCP, solitamente sulla porta 80: il client invia una richiesta, il server la elabora e invia una risposta. Accedendo a una pagina web, il browser richiede per primo il file HTML principale; una volta ricevuto, lo analizza e, se trova immagini o altri elementi, avvia nuove richieste HTTP per ciascuna risorsa aggiuntiva.
Connessioni non persistenti e persistenti
Nella forma più semplice (HTTP/1.0), la connessione TCP viene chiusa subito dopo l’invio della risposta: se una pagina richiede 10 risorse, servono 10 connessioni separate. Con HTTP/1.1 è stato introdotto il concetto di connessione persistente, che consente di riutilizzare la stessa connessione TCP per più richieste consecutive, migliorando sensibilmente le prestazioni. Le richieste possono essere inviate una alla volta oppure in modalità pipelined, cioè in sequenza senza attendere le risposte precedenti.
Con connessione non persistente, per una pagina con HTML + 5 immagini + 2 CSS + 1 JS = 9 connessioni TCP! Ogni connessione richiede 3-way handshake, quindi 9 * 3 pacchetti solo per aprire. Con persistente, 1 sola connessione TCP e 9 richieste dentro. Risparmiate 8 handshake, la pagina si carica in metà tempo. Ecco perché HTTP/1.1 è stato rivoluzionario nel 1997.
| Caratteristica | Non persistente (HTTP/1.0) | Persistente (HTTP/1.1) |
|---|---|---|
| Connessioni per 10 risorse | 10 | 1 |
| Overhead TCP | Alto | Basso |
| Velocità | Lenta | Veloce |
| Header | Connection: close | Connection: keep-alive |
4.1 Struttura dei messaggi HTTP
I messaggi HTTP, sia di richiesta che di risposta, seguono una struttura ben definita: una riga iniziale, un insieme di intestazioni (header) e, opzionalmente, un corpo del messaggio (body). Nella richiesta, la riga iniziale indica il metodo, la risorsa richiesta e la versione del protocollo: GET /percorso/file.html HTTP/1.1. Il corpo è presente solo in alcuni metodi, come POST o PUT, ed è usato per trasmettere dati al server. Nella risposta, la riga iniziale è invece una riga di stato.
Esempio — richiesta HTTP completa
Esempio — risposta HTTP completa
Gli header HTTP sono coppie nome: valore che descrivono le caratteristiche del messaggio: informazioni generali sulla trasmissione (es. Transfer-Encoding), caratteristiche dell’entità trasmessa (es. Content-Type, Expires), dettagli sulla richiesta (es. User-Agent, Host) o sulla risposta generata dal server (es. Server, WWW-Authenticate). Ho raccolto in tabella gli header più comuni, perché è il modo più rapido per consultarli quando servono davvero, durante lo sviluppo:
| Header | Dove compare | A cosa serve |
|---|---|---|
| Host | Richiesta | Indica il dominio a cui ci si rivolge (necessario con hosting virtuale) |
| User-Agent | Richiesta | Identifica browser e sistema operativo del client |
| Content-Type | Entrambi | Formato del corpo del messaggio (es. text/html, application/json) |
| Content-Length | Entrambi | Dimensione in byte del corpo del messaggio |
| Cache-Control / Expires | Risposta | Per quanto tempo la risorsa può essere conservata in cache |
| Server | Risposta | Software e versione del server che ha risposto |
Prima di HTTP/1.1 un server poteva ospitare un solo sito per IP. Con Host posso avere 100 domini diversi sullo stesso IP: www.azienda1.it e www.azienda2.it puntano allo stesso server, ma il server guarda l'header Host e capisce quale sito servire. È così che Altervista ospita migliaia di siti sullo stesso server. Senza Host non funzionerebbe il virtual hosting.
4.2 I metodi HTTP
I metodi HTTP esprimono l’azione che il client intende compiere sulla risorsa. Sono alla base delle applicazioni web moderne e delle architetture RESTful.
| Metodo | Descrizione |
|---|---|
| GET | Richiede una risorsa in sola lettura. I parametri viaggiano nell’URL, sotto forma di query string |
| POST | Invia dati al server, tipicamente da un form. I parametri viaggiano nel body, non nell’URL |
| PUT | Crea o aggiorna una risorsa specifica. È idempotente: ripeterlo produce sempre lo stesso risultato |
| DELETE | Richiede l’eliminazione di una risorsa, di norma identificata direttamente nell’URI |
PUT è idempotente: se faccio PUT /utenti/15 con email=mario@email.it 10 volte, alla fine ho sempre email=mario@email.it, non 10 email. POST non è idempotente: se faccio POST /ordini 10 volte, creo 10 ordini diversi! Se vi chiedono differenza PUT vs POST, dite questa: PUT = aggiorno una risorsa precisa, POST = creo una nuova risorsa.
4.2.1 Dove vanno i parametri: quattro esempi pratici
Ho preferito mostrare il procedimento completo, senza saltare i passaggi intermedi, per ciascuno dei quattro metodi: è l’unico modo per fissare davvero dove finiscono i parametri in ogni caso.
GET — ricerca di un prodotto
URL digitato: https://www.esempio.it/cerca?categoria=libri&autore=rossi
I parametri GET sono visibili nella barra degli indirizzi: non adatti a dati sensibili.
Mai mettere password in GET! Rimane nella cronologia, nei log del server, nei proxy. Se vedete https://sito.com/login?password=12345 è un sito fatto male. Usate sempre POST + HTTPS per dati sensibili.
POST — invio di un form di login
Con POST i parametri vanno nel body. E’ più sicuro di GET ma non cifra i dati: la sicurezza reale la garantisce HTTPS.
PUT — aggiornamento di un profilo utente
DELETE — eliminazione di un ordine
| Metodo | Dove vanno i parametri | Esiti tipici |
|---|---|---|
| GET | Query string nell’URL | 200 OK con la risorsa richiesta |
| POST | Corpo del messaggio | 200 OK, 201 Created |
| PUT | Corpo del messaggio | 201 Created (nuova risorsa) o 200/204 (aggiornamento) |
| DELETE | Direttamente nell’URI | 200 OK, 202 Accepted, 204 No Content |
GET = cerca (parametri in URL, come Google), POST = posta (imbuchi la lettera nel body), PUT = metti (metti dati nuovi nel body su risorsa precisa), DELETE = cancella (dici cosa cancellare direttamente nell'URI). Se ricordate "cerca, posta, metti, cancella" non vi confondete più.
4.3 I codici di stato HTTP
Ogni risposta HTTP contiene un codice di stato che indica l’esito della richiesta. I codici si raggruppano in cinque classi, identificate dalla prima cifra:
| Classe | Significato | Esempio |
|---|---|---|
| 1xx | Informativa: la richiesta è stata ricevuta, il processo continua | 100 Continue |
| 2xx | Successo: la richiesta è stata elaborata correttamente | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirezione: sono necessarie ulteriori azioni per completare la richiesta | 301 Moved Permanently, 304 Not Modified |
| 4xx | Errore del client: la richiesta contiene un errore o non è autorizzata | 404 Not Found, 403 Forbidden |
| 5xx | Errore del server: il server non è riuscito a soddisfare una richiesta valida | 500 Internal Server Error, 503 Service Unavailable |
200 OK
Indica che la richiesta è stata elaborata correttamente e la risorsa è stata restituita senza errori. Situazione tipica: un utente digita l’indirizzo di una pagina e il server risponde fornendo il contenuto richiesto.
404 Not Found
Il server è stato raggiunto correttamente, ma la risorsa richiesta non esiste o non è disponibile all’indirizzo specificato. Situazione tipica: una pagina eliminata o un URL scritto in modo errato.
200 = tutto ok, la pagina c'è. 301 = la pagina si è spostata per sempre, aggiorna i segnalibri. 304 = la pagina non è cambiata, usa la cache. 403 = non hai permessi, 404 = pagina non trovata, 500 = errore del programmatore, 503 = server sovraccarico. Quando il vostro sito dà 500, non è colpa dell'utente, è colpa vostra che avete scritto male il codice PHP.
4.4 La codifica URL
La codifica URL (URL encoding) trasforma una stringa di testo in un formato compatibile con la trasmissione tramite richieste HTTP. È fondamentale quando si inviano dati al server con i metodi GET e POST, in particolare nei moduli HTML e nelle query string: non tutti i caratteri, infatti, possono comparire direttamente in un URL, perché alcuni hanno un significato speciale o generano ambiguità.
Ad esempio, la stringa societa=Rossi & Martini, dopo la codifica, diventa societa=Rossi%26Martini: il carattere &, che in un URL separa i parametri, viene sostituito dalla sequenza %26, il suo valore ASCII in esadecimale. Lo stesso principio si applica ad altri caratteri speciali, come %, @, + e gli spazi (convertiti in %20). La codifica URL è usata soprattutto nelle query string, ma si applica anche ai link (tag <a href>), non solo ai moduli (tag <form>).
| Carattere | Codifica URL |
|---|---|
| Spazio | %20 |
| & | %26 |
| % | %25 |
| @ | %40 |
| + | %2B |
5. Analizzare il traffico HTTP
Per osservare e comprendere il funzionamento di HTTP in modo pratico, gli strumenti più immediati sono già dentro il browser: la scheda Network dei DevTools (F12) mostra, per ogni richiesta, il metodo usato, gli header inviati e ricevuti, il codice di stato e i tempi di risposta. Per un’analisi più a basso livello — fino ai singoli pacchetti TCP che trasportano i messaggi HTTP — si usa Wireshark, uno sniffer di rete che permette di ispezionare byte per byte una comunicazione reale tra client e server.
Ti consiglio di provare tu stesso ad aprire i DevTools durante la navigazione: vedere le richieste HTTP scorrere in tempo reale rende tutto molto più concreto di qualunque spiegazione teorica.
Apriamo Chrome su www.esempio.it, premiamo F12 -> Network -> ricarichiamo. Vedrete: 1 richiesta GET per HTML, poi 5 GET per immagini, 2 per CSS, 1 per JS. Cliccate su una richiesta e guardate Headers: vedete Host, User-Agent, Content-Type, Status Code. È esattamente quello che abbiamo studiato in teoria, ma dal vivo. Fatelo a casa, è il modo migliore per fissare HTTP.
6. Punti chiave
- Il modello client-server separa chi richiede (client) da chi fornisce (server) un servizio; sul Web, HTTP è il protocollo applicativo che regola questa comunicazione sopra TCP.
- I messaggi HTTP hanno una struttura fissa: riga iniziale (richiesta o stato), header, corpo opzionale. Con HTTP/1.1 le connessioni possono essere persistenti e riutilizzate per più richieste.
- I quattro metodi principali — GET, POST, PUT, DELETE — collocano i parametri in punti diversi (URL, corpo, corpo, URI) e sono alla base delle API RESTful.
- I codici di stato si dividono in cinque classi (1xx-5xx); 200 OK e 404 Not Found sono i più comuni nell’uso quotidiano.
- La codifica URL trasforma i caratteri speciali (spazio, &, %, @, +) in sequenze %XX per garantire la corretta trasmissione dei dati.
- Strumenti come i DevTools del browser e Wireshark permettono di osservare concretamente il traffico HTTP.
Vuoi passare all'azione? Accedi alla repository ufficiale GitHub del corso per scaricare il file del laboratorio pratico in formato .md.
🧪 Lab HTTPVuoi consultare la sezione dedicata ai laboratori sul sito? Accedi cliccando il pulsante qui sotto.
📊 Sezione dedicata ai Laboratori📚 Compito per casa - Diventate detective HTTP
Aprite la vostra home di Altervista con DevTools -> Network. Contate quante richieste fa, quanti 200, se ci sono 301 o 304. Cercate l'header Server: cosa vi dice? Poi provate a digitare una pagina che non esiste e guardate il 404. La prossima lezione costruiamo una Web App e vedremo questi metodi in azione con codice vero.