Formazione di Express e Node.js da StrongLoop

Questa traduzione fornita da StrongLoop / IBM.

È possibile che questo documento non sia aggiornato poiché la documentazione è in inglese. Per gli ultimi aggiornamenti, fare riferimento alla documentazione in inglese.

Utilizzo del middleware

Express è un framework Web di routing e middleware, con funzionalità sua propria minima: un’applicazione Express è essenzialmente a serie di chiamate a funzioni middleware.

Le funzioni middleware sono funzioni con accesso all’oggetto richiesta (req), all’oggetto risposta (res) e alla successiva funzione middleware nel ciclo richiesta-risposta dell’applicazione. La successiva funzione middleware viene comunemente denotata da una variabile denominata next.

Le funzioni middleware possono eseguire le attività elencate di seguito:

Se la funzione middleware corrente non termina il ciclo richiesta-risposta, deve richiamare next() per passare il controllo alla successiva funzione middleware. Altrimenti, la richiesta verrà lasciata in sospeso.

Un’applicazione Express può utilizzare i seguenti tipi di middleware:

È possibile caricare il middleware a livello dell’applicazione e del router con un percorso di montaggio facoltativo. È possibile inoltre caricare una serie di funzioni middleware contemporaneamente e, in questo modo, si crea un sotto-stack del sistema middleware in un punto di montaggio.

Middleware a livello dell'applicazione

Associare il middleware al livello dell’applicazione ad un’istanza dell’oggetto app utilizzando le funzioni app.use() e app.METHOD(), dove METHOD corrisponde al metodo HTTP della richiesta che la funzione middleware gestisce (ad esempio GET, PUT o POST) in lettere minuscole.

Questo esempio presenta una funzione middleware senza percorso di montaggio. La funzione viene eseguita ogni volta che l’app riceve una richiesta.


var app = express();

app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

Questo esempio presenta una funzione middleware montata nel percorso /user/:id. La funzione viene eseguita per qualsiasi tipo di richiesta HTTP nel percorso /user/:id.


app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

Questo esempio presenta una route e la relativa funzione handler (sistema middleware). La funzione gestisce richieste GET nel percorso /user/:id.


app.get('/user/:id', function (req, res, next) {
  res.send('USER');
});

Ecco un esempio di caricamento di una serie di funzioni middleware in un punto di montaggio, con un percorso di montaggio. Illustra un sotto-stack middleware che stampa informazioni sulla richiesta per qualsiasi tipo di richiesta HTTP nel percorso /user/:id.


app.use('/user/:id', function(req, res, next) {
  console.log('Request URL:', req.originalUrl);
  next();
}, function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

Gli handler di route consentono di definire molteplici route per un percorso. Nell’esempio sottostante sono definite due route per richieste GET nel percorso /user/:id. La seconda route non provocherà alcun problema, ma non verrà mai chiamata, poiché la prima route termina il ciclo di richiesta-risposta.

Questo esempio presenta un sotto-stack middleware che gestisce richieste GET nel percorso /user/:id.


app.get('/user/:id', function (req, res, next) {
  console.log('ID:', req.params.id);
  next();
}, function (req, res, next) {
  res.send('User Info');
});

// handler for the /user/:id path, which prints the user ID
app.get('/user/:id', function (req, res, next) {
  res.end(req.params.id);
});

Per ignorare le restanti funzioni middleware da uno stack di middleware del router, richiamare next('route') per passare il controllo alla route successiva. NOTA: next('route') funzionerà solo in funzioni middleware che sono state caricate utilizzando le funzioni app.METHOD() o router.METHOD().

Questo esempio presenta un sotto-stack middleware che gestisce richieste GET nel percorso /user/:id.


app.get('/user/:id', function (req, res, next) {
  // if the user ID is 0, skip to the next route
  if (req.params.id == 0) next('route');
  // otherwise pass the control to the next middleware function in this stack
  else next(); //
}, function (req, res, next) {
  // render a regular page
  res.render('regular');
});

// handler for the /user/:id path, which renders a special page
app.get('/user/:id', function (req, res, next) {
  res.render('special');
});

Middleware a livello del router

Il middleware a livello del router funziona nello stesso modo di quello a livello dell’applicazione, fatta eccezione per il fatto di essere associato ad un’istanza di express.Router().


var router = express.Router();

Caricare il middleware a livello del router utilizzando le funzioni router.use() e router.METHOD().

Il seguente codice di esempio replica il sistema middleware mostrato sopra per il middleware a livello dell’applicazione, utilizzando il middleware a livello del router:


var app = express();
var router = express.Router();

// a middleware function with no mount path. This code is executed for every request to the router
router.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
router.use('/user/:id', function(req, res, next) {
  console.log('Request URL:', req.originalUrl);
  next();
}, function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

// a middleware sub-stack that handles GET requests to the /user/:id path
router.get('/user/:id', function (req, res, next) {
  // if the user ID is 0, skip to the next router
  if (req.params.id == 0) next('route');
  // otherwise pass control to the next middleware function in this stack
  else next(); //
}, function (req, res, next) {
  // render a regular page
  res.render('regular');
});

// handler for the /user/:id path, which renders a special page
router.get('/user/:id', function (req, res, next) {
  console.log(req.params.id);
  res.render('special');
});

// mount the router on the app
app.use('/', router);

Middleware di gestione degli errori

Il middleware di gestione degli errori impiega sempre quattro argomenti. È necessario fornire quattro argomenti per identificarlo come funzione middleware di gestione degli errori. Anche se non è necessario utilizzare l’oggetto next, lo si deve specificare per mantenere la firma. Altrimenti, l’oggetto next verrà interpretato come middleware regolare e non sarà in grado di gestire gli errori.

Definire le funzioni middleware di gestione degli errori nello stesso modo delle altre funzioni middleware, ma con quattro argomenti invece di tre, nello specifico con la firma (err, req, res, next)):


app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

Per dettagli sul middleware di gestione degli errori, consultare la sezione: Gestione degli errori.

Middleware integrato

Dalla versione 4.x, Express non dipende più da Connect. Fatta eccezione per express.static, tutte le funzioni middleware che prima erano state incluse in Express, ora sono in moduli separati. Vedere l’elenco delle funzioni middleware.

express.static(root, [options])

L’unica funzione middleware integrata in Express è express.static. Questa funzione è basata su serve-static ed è responsabile della fornitura degli asset statici di un’applicazione Express.

L’argomento root specifica la directory root da cui fornire gli asset statici.

L’oggetto facoltativo options può avere le seguenti proprietà:

Proprietà Descrizione Tipo Valore predefinito
dotfiles Opzione per la fornitura di dotfiles. Valori possibili sono “allow”, “deny” e “ignore” Stringa “ignore”
etag Abilitare o disabilitare la generazione di etag Booleano true
extensions Imposta i fallback dell’estensione file. Array []
index Invia un file di indice di directory. Impostare su false per disabilitare l’indicizzazione della directory. Misto “index.html”
lastModified Impostare l’intestazione Last-Modifiedsulla data dell’ultima modifica del file nel sistema operativo. I valori possibili sono true o false. Booleano true
maxAge Impostare la proprietà dell’intestazione Cache-Control, in millisecondi o una stringa in formato ms Numero 0
redirect Reindirizzare al carattere “/” finale, quando il nome percorso è una directory. Booleano true
setHeaders Funzione per l’impostazione delle intestazioni HTTP perché siano adatte al file. Funzione  

Ecco un esempio di utilizzo della funzione middleware express.static con un oggetto opzioni elaborato:


var options = {
  dotfiles: 'ignore',
  etag: false,
  extensions: ['htm', 'html'],
  index: false,
  maxAge: '1d',
  redirect: false,
  setHeaders: function (res, path, stat) {
    res.set('x-timestamp', Date.now());
  }
}

app.use(express.static('public', options));

È possibile avere più di una directory statica per app:


app.use(express.static('public'));
app.use(express.static('uploads'));
app.use(express.static('files'));

Per ulteriori dettagli sulla funzione serve-static e sulle relative opzioni, consultare: documentazione serve-static.

Middleware di terzi

Utilizzare il middleware di terzi per aggiungere funzionalità alle app Express.

Installare il modulo Node.js per la funzionalità richiesta, quindi, caricarlo nella propria app a livello dell’applicazione o a livello del router.

Il seguente esempio illustra l’installazione e il caricamento della funzione middleware di analisi dei cookie cookie-parser.


$ npm install cookie-parser


var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');

// load the cookie-parsing middleware
app.use(cookieParser());

Per un elenco parziale delle funzioni middleware di terzi comunemente utilizzate con Express, consultare la sezione: Middleware di terzi.