In Express, req.params contiene i valori dei segmenti con nome nel path della route (/users/:id dà req.params.id), req.query contiene la query string dopo il ? (/search?q=node dà req.query.q) e req.body contiene i dati inviati nel body della richiesta. req.params e req.query vengono riempiti a ogni richiesta, ma req.body resta undefined finché un body parser come app.use(express.json()) non lo legge. I valori di params e query sono sempre stringhe.
La prima richiesta risponde {"params":{"userId":"7"},"query":{"sort":"new","limit":"2"}}. Nota le virgolette: 7 e 2 sono stringhe, quindi convertile con Number() prima di fare calcoli o confronti con numeri. Ora cambia il metodo in POST, lascia il path /users/7/posts e invia il body {"title": "Hello", "draft": true}: la risposta è 201 con "body":{"title":"Hello","draft":true}, dove true è un vero booleano perché arriva dal JSON.
req.params, req.query e req.body a confronto
req.params | req.query | req.body | |
|---|---|---|---|
| Arriva da | Il path, /users/:id | La query string, ?sort=new | Il body della richiesta |
| URL o body di esempio | /users/7 | /users?sort=new | {"name": "Ada"} |
| Valore | { id: '7' } | { sort: 'new' } | { name: 'Ada' } |
| Tipi | Stringhe | Stringhe e array di stringhe | Quello che contiene il JSON |
| Cosa serve | Un :name nella route | Niente | app.use(express.json()) |
| Uso tipico | Quale risorsa | Filtrare, ordinare, paginare | Dati da creare o aggiornare |
Una route può avere più parametri, e ogni nome diventa una chiave di req.params: /teams/:teamId/members/:memberId dà entrambi gli id. Anche un trattino o un punto li separano, quindi /flights/:from-:to trasforma /flights/LAX-SFO in { from: 'LAX', to: 'SFO' }.
req.query con chiavi ripetute o mancanti
Una chiave che compare due volte diventa un array, e una chiave che manca è undefined, quindi dai un valore di default alle opzioni:
La risposta è {"page":1,"tags":["red","sale"],"raw":{"tag":["red","sale"]}}. Invia GET /products?tag=red&page=3 e tags è comunque un array, ["red"], perché [].concat() trasforma sia una stringa sia un array in un array. Express 5 analizza le query string con il parser semplice di Node, quindi ?filter[size]=m dà la chiave "filter[size]", non un oggetto annidato; Express 4 lo annidava.
req.body ha bisogno di express.json()
Node consegna il body come uno stream di byte. express.json() lo legge, lo analizza e imposta req.body, ma solo quando la richiesta ha Content-Type: application/json. I form HTML inviano application/x-www-form-urlencoded, che richiede invece express.urlencoded().
Invia POST /signup con il body {"email": "ada@example.com"} e ottieni 201 con {"email":"ada@example.com","name":"anonymous"}. Invia un body vuoto e ottieni 400. Il ?? {} è importante: senza, destrutturare undefined lancia un TypeError su ogni richiesta senza body JSON. Per validare davvero forma e tipi, usa una libreria di schemi come zod.
req.headers e req.get()
req.headers è un oggetto con tutti gli header della richiesta, con i nomi in minuscolo. req.get(name) legge un header ignorando maiuscole e minuscole, quindi req.get('Content-Type') e req.get('content-type') restituiscono lo stesso valore. Qualche altra proprietà che userai:
path è /whoami e originalUrl è /whoami?debug=1. Aggiungi l'header Authorization: Bearer abc nella barra della richiesta e inviala di nuovo: token diventa "Bearer abc". Dentro un router montato con app.use('/api', router), req.path perde il prefisso /api mentre req.originalUrl lo mantiene (il routing di Express spiega il montaggio).
Errori comuni
Leggere req.body in una richiesta GET. I browser e la maggior parte dei client non inviano un body con GET. Metti le opzioni di una GET nella query string.
Controllare un flag della query come se fosse un booleano. ?admin=false dà la stringa 'false', che è truthy, quindi if (req.query.admin) passa. Confronta stringhe: req.query.admin === 'true'.
Inviare JSON senza l'header. Un client che invia JSON come text/plain ottiene req.body === undefined. Imposta Content-Type: application/json sul client.
Domande frequenti
Come ottengo l'indirizzo IP del client in Express?
Leggi req.ip. Dietro un proxy o un load balancer è l'indirizzo del proxy finché non imposti app.set('trust proxy', 1), che fa leggere a Express l'header X-Forwarded-For.
Come ottengo l'URL completo di una richiesta in Express?
req.originalUrl è il path più la query string come li ha inviati il client. Costruisci l'URL assoluto con `${req.protocol}://${req.get('host')}${req.originalUrl}`.
Come gestisco l'upload di file in Express?
Gli upload di file arrivano come multipart/form-data, che express.json() ed express.urlencoded() non analizzano. Usa un pacchetto come multer, che mette i file in req.file o req.files e gli altri campi in req.body.
Come leggo un cookie dalla richiesta?
L'header grezzo è in req.get('cookie'). Per avere un oggetto in req.cookies, installa il pacchetto cookie-parser e aggiungi app.use(cookieParser()).