Ricerca…


introduzione

Express è un framework di applicazioni web Node.js minimale e flessibile, che fornisce un robusto set di funzionalità per la creazione di applicazioni Web.

Il sito web ufficiale di Express è expressjs.com . La fonte può essere trovata su GitHub .

Sintassi

  • app.get (percorso [, middleware], callback [, callback ...])
  • app.put (percorso [, middleware], callback [, callback ...])
  • app.post (percorso [, middleware], callback [, callback ...])
  • app ['delete'] (percorso [, middleware], callback [, callback ...])
  • app.use (percorso [, middleware], callback [, callback ...])
  • app.use (callback)

Parametri

Parametro Dettagli
path Specifica la parte del percorso o l'URL che verrà gestito dal callback specificato.
middleware Una o più funzioni che verranno chiamate prima della richiamata. Essenzialmente un concatenamento di più funzioni di callback . Utile per una gestione più specifica, ad esempio l'autorizzazione o la gestione degli errori.
callback Una funzione che verrà utilizzata per gestire le richieste nel path specificato. Sarà chiamato come callback(request, response, next) , dove request , response e next sono descritti di seguito.
request richiamata Un oggetto che incapsula i dettagli sulla richiesta HTTP che il callback è stato chiamato a gestire.
response Un oggetto che viene utilizzato per specificare in che modo il server deve rispondere alla richiesta.
next Un callback che passa il controllo sulla prossima route corrispondente. Accetta un oggetto errore opzionale.

Iniziare

Dovrai prima creare una directory, accedervi nella tua shell e installare Express usando npm eseguendo npm install express --save

Crea un file e app.js e aggiungi il codice seguente che crea un nuovo server Express e aggiunge un endpoint ( /ping ) con il metodo app.get :

const express = require('express');

const app = express();

app.get('/ping', (request, response) => {
    response.send('pong');
});

app.listen(8080, 'localhost');

Per eseguire il tuo script usa il seguente comando nella tua shell:

> node app.js

La tua applicazione accetterà le connessioni sulla porta localhost 8080. Se l'argomento nome host per app.listen viene omesso, il server accetterà le connessioni sull'indirizzo IP della macchina e su localhost. Se il valore della porta è 0, il sistema operativo assegnerà una porta disponibile.

Una volta che lo script è in esecuzione, puoi testarlo in una shell per confermare che ottieni la risposta prevista, "pong", dal server:

> curl http://localhost:8080/ping
pong

È anche possibile aprire un browser Web, accedere all'URL http: // localhost: 8080 / ping per visualizzare l'output

Routing di base

Per prima cosa crea un'app express:

const express = require('express');
const app = express();

Quindi puoi definire percorsi come questo:

app.get('/someUri', function (req, res, next) {})

Questa struttura funziona per tutti i metodi HTTP e prevede un percorso come primo argomento e un gestore per quel percorso, che riceve gli oggetti richiesta e risposta. Quindi, per i metodi HTTP di base, questi sono i percorsi

// GET www.domain.com/myPath
app.get('/myPath', function (req, res, next) {})

// POST www.domain.com/myPath
app.post('/myPath', function (req, res, next) {})

// PUT www.domain.com/myPath
app.put('/myPath', function (req, res, next) {})

// DELETE www.domain.com/myPath
app.delete('/myPath', function (req, res, next) {})

Puoi controllare l'elenco completo dei verbi supportati qui . Se si desidera definire lo stesso comportamento per una route e tutti i metodi HTTP, è possibile utilizzare:

app.all('/myPath', function (req, res, next) {}) 

o

app.use('/myPath', function (req, res, next) {})

o

app.use('*', function (req, res, next) {})

// * wildcard will route for all paths

È possibile concatenare le definizioni del percorso per un singolo percorso

app.route('/myPath')
  .get(function (req, res, next) {})
  .post(function (req, res, next) {})
  .put(function (req, res, next) {})

È inoltre possibile aggiungere funzioni a qualsiasi metodo HTTP. Eseguiranno prima del callback finale e prenderanno come parametri i parametri (req, res, next).

// GET www.domain.com/myPath
app.get('/myPath', myFunction, function (req, res, next) {})

Le tue callback finali possono essere archiviate in un file esterno per evitare di inserire troppo codice in un file:

// other.js
exports.doSomething = function(req, res, next) {/* do some stuff */};

E poi nel file contenente i tuoi percorsi:

const other = require('./other.js');
app.get('/someUri', myFunction, other.doSomething);

Questo renderà il tuo codice molto più pulito.

Ottenere informazioni dalla richiesta

Per ottenere informazioni dall'URL richiedente (notare che req è l'oggetto richiesta nella funzione di gestione dei percorsi). Considera questa definizione di percorso /settings/:user_id e questo particolare esempio /settings/32135?field=name

// get the full path
req.originalUrl // => /settings/32135?field=name

// get the user_id param
req.params.user_id // => 32135     

// get the query value of the field
req.query.field // => 'name'

Puoi anche ottenere intestazioni della richiesta, come questa

req.get('Content-Type')
// "text/plain"

Per semplificare l'acquisizione di altre informazioni puoi usare i middleware. Ad esempio, per ottenere le informazioni sulla body della richiesta, è possibile utilizzare il middleware body-parser , che trasformerà il corpo della richiesta grezza in formato utilizzabile.

var app = require('express')();
var bodyParser = require('body-parser');

app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded

Supponiamo ora una richiesta come questa

PUT /settings/32135
{
  "name": "Peter"
}

Puoi accedere al nome postato come questo

req.body.name
// "Peter"

In modo simile, puoi accedere ai cookie dalla richiesta, hai anche bisogno di un middleware come cookie-parser

req.cookies.name

Applicazione espressa modulare

Per rendere le fabbriche di router di applicazioni modulari per uso express:

Modulo:

// greet.js
const express = require('express');

module.exports = function(options = {}) { // Router factory
    const router = express.Router();

    router.get('/greet', (req, res, next) => {
        res.end(options.greeting);
    });

    return router;
};

Applicazione:

// app.js
const express = require('express');
const greetMiddleware = require('./greet.js');

express()
    .use('/api/v1/', greetMiddleware({ greeting:'Hello world' }))
    .listen(8080);

Ciò renderà la tua applicazione modulare, personalizzabile e il tuo codice riutilizzabile.

Quando si accede a http://<hostname>:8080/api/v1/greet l'output sarà Hello world

Esempio più complicato

Esempio con servizi che mostrano vantaggi di fabbrica del middleware.

Modulo:

// greet.js
const express = require('express');

module.exports = function(options = {}) { // Router factory
    const router = express.Router();
    // Get controller
    const {service} = options;

    router.get('/greet', (req, res, next) => {
        res.end(
            service.createGreeting(req.query.name || 'Stranger')
        );
    });

    return router;
};

Applicazione:

// app.js
const express = require('express');
const greetMiddleware = require('./greet.js');

class GreetingService {
    constructor(greeting = 'Hello') {
        this.greeting = greeting;
    }

    createGreeting(name) {
        return `${this.greeting}, ${name}!`;
    }
}

express()
    .use('/api/v1/service1', greetMiddleware({
        service: new GreetingService('Hello'),
    }))
    .use('/api/v1/service2', greetMiddleware({
        service: new GreetingService('Hi'),
    }))
    .listen(8080);

Quando si accede a http://<hostname>:8080/api/v1/service1/greet?name=World l'output sarà Hello, World e accederà a http://<hostname>:8080/api/v1/service2/greet?name=World l'output sarà Hi, World .

Utilizzo di un motore di modelli

Utilizzo di un motore di modelli

Il codice seguente configurerà Jade come motore di template. (Nota: Jade è stata ribattezzata come pug a dicembre 2015.)

const express = require('express');  //Imports the express module
const app = express();  //Creates an instance of the express module

const PORT = 3000; //Randomly chosen port

app.set('view engine','jade'); //Sets jade as the View Engine / Template Engine
app.set('views','src/views'); //Sets the directory where all the views (.jade files) are stored.

//Creates a Root Route
app.get('/',function(req, res){
    res.render('index');  //renders the index.jade file into html and returns as a response. The render function optionally takes the data to pass to the view.
});

//Starts the Express server with a callback
app.listen(PORT, function(err) {
    if (!err) {
        console.log('Server is running at port', PORT);
    } else {
        console.log(JSON.stringify(err));
    }
});

Allo stesso modo, potrebbero essere utilizzati anche altri modelli di template come Handlebars ( hbs ) o ejs . Ricorda di npm install il motore di template. Per Handlebars utilizziamo il pacchetto hbs , per Jade abbiamo un pacchetto jade e per EJS abbiamo un pacchetto ejs .

Esempio di modello EJS

Con EJS (come altri modelli express), puoi eseguire il codice del server e accedere alle tue variabili del server dal tuo HTML.
In EJS è fatto usando " <% " come tag di inizio e " %> " come tag di fine, le variabili passate come parametri di rendering sono accessibili usando <%=var_name%>
Ad esempio, se si dispone di array di forniture nel codice del server
puoi ricollegarlo usando

<h1><%= title %></h1>
   <ul>
<% for(var i=0; i<supplies.length; i++) { %>
    <li>
        <a href='supplies/<%= supplies[i] %>'>
            <%= supplies[i] %>
        </a>
    </li>
<% } %>

Come puoi vedere nell'esempio ogni volta che cambi codice server e HTML devi chiudere il tag EJS corrente e aprirne uno successivo, qui abbiamo voluto creare li dentro il comando for quindi abbiamo dovuto chiudere il nostro tag EJS alla fine del for e crea un nuovo tag solo per le parentesi graffe
un altro esempio
se vogliamo inserire la versione predefinita di input come variabile dal lato server, usiamo <%=
per esempio:

 Message:<br>
<input type="text" value="<%= message %>" name="message" required>

Qui la variabile del messaggio passata dal lato server sarà il valore predefinito del tuo input, tieni presente che se non hai passato la variabile del messaggio dal lato server, EJS genererà un'eccezione. Puoi passare i parametri usando res.render('index', {message: message}); (per il file ejs chiamato index.ejs).

Nei tag EJS puoi anche utilizzare if , while o qualsiasi altro comando javascript che desideri.

API JSON con ExpressJS

var express = require('express');
var cors = require('cors'); // Use cors module for enable Cross-origin resource sharing

var app = express();
app.use(cors()); // for all routes

var port = process.env.PORT || 8080;

app.get('/', function(req, res) {
    var info = {
        'string_value': 'StackOverflow',
        'number_value': 8476
    }
    res.json(info);

    // or
    /* res.send(JSON.stringify({
        string_value: 'StackOverflow',
        number_value: 8476
    })) */

  //you can add a status code to the json response
   /* res.status(200).json(info) */
})

app.listen(port, function() {
    console.log('Node.js listening on port ' + port)
})

Su http://localhost:8080/ oggetto di output

{
    string_value: "StackOverflow",
    number_value: 8476
}

Servire file statici

Quando si crea un server Web con Express, è spesso richiesto di offrire una combinazione di contenuti dinamici e file statici.

Ad esempio, potresti avere index.html e script.js che sono file statici mantenuti nel file system.

È comune utilizzare la cartella denominata "public" per avere file statici. In questo caso la struttura della cartella potrebbe essere simile a:

project root
├── server.js
├── package.json 
└── public
    ├── index.html
    └── script.js

Ecco come configurare Express per servire file statici:

const express = require('express');
const app = express();

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

Nota: una volta configurata la cartella, index.html, script.js e tutti i file nella cartella "pubblica" saranno disponibili nel percorso principale (non è necessario specificare /public/ nell'URL). Questo perché, express cerca i file relativi alla cartella statica configurata. È possibile specificare il prefisso del percorso virtuale come mostrato di seguito:

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

renderà le risorse disponibili sotto /static/ prefisso.

Più cartelle

È possibile definire più cartelle contemporaneamente:

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

Quando serve le risorse Express esaminerà la cartella nell'ordine di definizione. In caso di file con lo stesso nome, verrà pubblicato quello nella prima cartella di corrispondenza.

Percorsi con nomi in stile Django

Un grosso problema è che le rotte con nome prezioso non sono supportate da Express out of the box. La soluzione è installare il pacchetto di terze parti supportato, ad esempio express-reverse :

npm install express-reverse

Collegalo al tuo progetto:

var app = require('express')();
require('express-reverse')(app);

Quindi usarlo come:

app.get('test', '/hello', function(req, res) {
  res.end('hello');
});

Lo svantaggio di questo approccio è che non è possibile utilizzare il modulo Express route come mostrato nell'utilizzo avanzato del router . La soluzione alternativa è passare la tua app come parametro alla tua fabbrica di router:

require('./middlewares/routing')(app);

E usalo come:

module.exports = (app) => {
    app.get('test', '/hello', function(req, res) {
      res.end('hello');
    });
};

Da ora in poi puoi capire come definire le funzioni per unirle con spazi dei nomi personalizzati specificati e puntare ai controller appropriati.

Gestione degli errori

Gestione degli errori di base

Per impostazione predefinita, Express cercherà una vista "errore" nella directory /views per il rendering. Basta creare la vista 'errore' e posizionarla nella directory views per gestire gli errori. Gli errori vengono scritti con il messaggio di errore, lo stato e la traccia dello stack, ad esempio:

views / error.pug

html
  body
      h1= message
      h2= error.status
      p= error.stack

Gestione avanzata degli errori

Definisci le tue funzioni middleware di gestione degli errori alla fine dello stack di funzioni middleware. Questi hanno quattro argomenti invece di tre (err, req, res, next) per esempio:

app.js

// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;

    //pass error to the next matching route.
    next(err);
});

// handle error, print stacktrace
app.use(function(err, req, res, next) {
    res.status(err.status || 500);

    res.render('error', {
        message: err.message,
        error: err
    });
});

È possibile definire diverse funzioni middleware di gestione degli errori, proprio come si farebbe con le normali funzioni middleware.

Utilizzo del middleware e della prossima richiamata

Express passa una next richiamata a tutte le funzioni di gestore di route e middleware che possono essere utilizzate per interrompere la logica per rotte singole su più gestori. La chiamata a next() senza argomenti indica a express di continuare con il prossimo middleware o gestore di route corrispondente. Se si chiama next(err) con un errore, verrà attivato qualsiasi middleware del gestore degli errori. La chiamata next('route') ignorerà qualsiasi middleware successivo sulla rotta corrente e passerà alla successiva route corrispondente. Ciò consente di disaccoppiare la logica del dominio in componenti riutilizzabili che sono autonomi, più semplici da testare e più facili da mantenere e modificare.

Più percorsi di corrispondenza

Le richieste a /api/foo o a /api/bar eseguiranno il gestore iniziale per cercare il membro e quindi passare il controllo al gestore effettivo per ogni percorso.

app.get('/api', function(req, res, next) {
  // Both /api/foo and /api/bar will run this
  lookupMember(function(err, member) {
    if (err) return next(err);
    req.member = member;
    next();
  });
});

app.get('/api/foo', function(req, res, next) {
  // Only /api/foo will run this
  doSomethingWithMember(req.member);
});

app.get('/api/bar', function(req, res, next) {
  // Only /api/bar will run this
  doSomethingDifferentWithMember(req.member);
});

Gestore degli errori

I gestori degli errori sono middleware con la function(err, req, res, next) firma function(err, req, res, next) . Possono essere impostati per percorso (ad esempio app.get('/foo', function(err, req, res, next) ) ma in genere, un singolo gestore di errori che esegue il rendering di una pagina di errore è sufficiente.

app.get('/foo', function(req, res, next) {
  doSomethingAsync(function(err, data) {
    if (err) return next(err);
    renderPage(data);
  });
});

// In the case that doSomethingAsync return an error, this special
// error handler middleware will be called with the error as the 
// first parameter.
app.use(function(err, req, res, next) {
  renderErrorPage(err);
});

middleware

Ciascuna delle funzioni di cui sopra è in realtà una funzione middleware che viene eseguita ogni volta che una richiesta corrisponde alla rotta definita, ma qualsiasi numero di funzioni middleware può essere definito su una singola rotta. Ciò consente di definire il middleware in file separati e la logica comune da riutilizzare su più percorsi.

app.get('/bananas', function(req, res, next) {
  getMember(function(err, member) {
    if (err) return next(err);
    // If there's no member, don't try to look
    // up data. Just go render the page now.
    if (!member) return next('route');
    // Otherwise, call the next middleware and fetch
    // the member's data.
    req.member = member;
    next();
  });
}, function(req, res, next) {
  getMemberData(req.member, function(err, data) {
    if (err) return next(err);
    // If this member has no data, don't bother
    // parsing it. Just go render the page now.
    if (!data) return next('route');
    // Otherwise, call the next middleware and parse
    // the member's data. THEN render the page.
    req.member.data = data;
    next();
  });
}, function(req, res, next) {
  req.member.parsedData = parseMemberData(req.member.data);
  next();
});

app.get('/bananas', function(req, res, next) {
  renderBananas(req.member);
});

In questo esempio, ciascuna funzione middleware potrebbe trovarsi nel proprio file o in una variabile altrove nel file in modo che possa essere riutilizzata in altre route.

Gestione degli errori

I documenti di base possono essere trovati qui

app.get('/path/:id(\\d+)', function (req, res, next) { // please note: "next" is passed
    if (req.params.id == 0) // validate param
        return next(new Error('Id is 0')); // go to first Error handler, see below

    // Catch error on sync operation
    var data;
    try {
        data = JSON.parse('/file.json');
    } catch (err) {
        return next(err);
    }

    // If some critical error then stop application
    if (!data)
        throw new Error('Smth wrong');

    // If you need send extra info to Error handler
    // then send custom error (see Appendix B)
    if (smth)
        next(new MyError('smth wrong', arg1, arg2))

    // Finish request by res.render or res.end
    res.status(200).end('OK');
});    

// Be sure: order of app.use have matter
// Error handler
app.use(function(err, req, res, next)) {
    if (smth-check, e.g. req.url != 'POST') 
        return next(err); // go-to Error handler 2.

    console.log(req.url, err.message);

    if (req.xhr) // if req via ajax then send json else render error-page
        res.json(err);
    else 
        res.render('error.html', {error: err.message});  
});

// Error handler 2
app.use(function(err, req, res, next)) {
    // do smth here e.g. check that error is MyError
    if (err instanceof MyError) {
        console.log(err.message, err.arg1, err.arg2);
    }     
    ...
    res.end();
});

Appendice A

// "In Express, 404 responses are not the result of an error, 
// so the error-handler middleware will not capture them." 
// You can change it.
app.use(function(req, res, next) {
    next(new Error(404)); 
});

Appendice B

// How to define custom error
var util = require('util');
...
function MyError(message, arg1, arg2) {
    this.message = message;
    this.arg1 = arg1;
    this.arg2 = arg2;
    Error.captureStackTrace(this, MyError);
}
util.inherits(MyError, Error);
MyError.prototype.name = 'MyError';

Hook: come eseguire il codice prima di qualsiasi req e dopo qualsiasi res

app.use() e middleware possono essere utilizzati per "before" e una combinazione di eventi close e finish può essere utilizzata per "after".

app.use(function (req, res, next) {
    function afterResponse() {
        res.removeListener('finish', afterResponse);
        res.removeListener('close', afterResponse);

        // actions after response
    }
    res.on('finish', afterResponse);
    res.on('close', afterResponse);

    // action before request
    // eventually calling `next()`
    next();
});
...
app.use(app.router);

Un esempio di questo è il middleware del logger , che verrà aggiunto al log dopo la risposta per impostazione predefinita.

Assicurati che questo "middleware" sia utilizzato prima di app.router quanto l'ordine è importante.


Il post originale è qui

Gestire richieste POST

Proprio come gestisci le richieste get in Express con il metodo app.get, puoi utilizzare il metodo app.post per gestire le richieste post.

Ma prima di poter gestire le richieste POST, sarà necessario utilizzare il middleware body-parser . Semplicemente analizza il corpo di POST , PUT , DELETE e altre richieste.

Body-Parser middleware Body-Parser analizza il corpo della richiesta e lo trasforma in un oggetto disponibile in req.body

var bodyParser = require('body-parser');

const express = require('express');

const app = express();

// Parses the body for POST, PUT, DELETE, etc.
app.use(bodyParser.json());

app.use(bodyParser.urlencoded({ extended: true }));

app.post('/post-data-here', function(req, res, next){

    console.log(req.body); // req.body contains the parsed body of the request.

});

app.listen(8080, 'localhost');

Di seguito è riportato un esempio per l'impostazione e la lettura dei cookie utilizzando il modulo cookie-parser :

var express = require('express');
var cookieParser = require('cookie-parser'); // module for parsing cookies
var app = express();
app.use(cookieParser());

app.get('/setcookie', function(req, res){
    // setting cookies
    res.cookie('username', 'john doe', { maxAge: 900000, httpOnly: true });
    return res.send('Cookie has been set');
});

app.get('/getcookie', function(req, res) {
    var username = req.cookies['username'];
    if (username) {
        return res.send(username);        
    }

    return res.send('No cookie found');
});

app.listen(3000);

Middleware personalizzato in Express

In Express, è possibile definire i middleware che possono essere utilizzati per controllare le richieste o impostare alcune intestazioni in risposta.

app.use(function(req, res, next){ });    // signature

Esempio

Il codice seguente aggiunge l' user all'oggetto richiesta e passa il controllo alla successiva route corrispondente.

var express = require('express');
var app = express();

//each request will pass through it
app.use(function(req, res, next){
    req.user = 'testuser';
    next();    // it will pass the control to next matching route
});

app.get('/', function(req, res){
    var user = req.user;
    console.log(user); // testuser
    return res.send(user);
});

app.listen(3000);

Gestione degli errori in Express

In Express, è possibile definire un gestore di errori unificato per la gestione degli errori verificatisi nell'applicazione. Definire quindi il gestore alla fine di tutti i percorsi e il codice logico.

Esempio

var express = require('express');
var app = express();

//GET /names/john
app.get('/names/:name', function(req, res, next){
    if (req.params.name == 'john'){
        return res.send('Valid Name');
    } else{
        next(new Error('Not valid name'));    //pass to error handler
    }
});

//error handler
app.use(function(err, req, res, next){
    console.log(err.stack);    // e.g., Not valid name
    return res.status(500).send('Internal Server Occured');
});

app.listen(3000);

Aggiunta di middleware

Le funzioni middleware sono funzioni che hanno accesso all'oggetto richiesta (req), all'oggetto risposta (res) e alla funzione middleware successiva nel ciclo richiesta-risposta dell'applicazione.

Le funzioni middleware possono eseguire qualsiasi codice, apportare modifiche agli oggetti res e req , al ciclo di risposta finale e chiamare il prossimo middleware.

Esempio molto comune di middleware è il modulo cors . Per aggiungere il supporto CORS, è sufficiente installarlo, richiederlo e inserire questa riga:

app.use(cors());

prima di qualsiasi router o funzione di routing.

Ciao mondo

Qui creiamo un semplice server mondiale Hello usando Express. Itinerari:

  • '/'
  • '/ Wiki'

E per il riposo darà "404", cioè la pagina non trovata.

'use strict';

const port = process.env.PORT || 3000;

var app = require('express')();
    app.listen(port);

app.get('/',(req,res)=>res.send('HelloWorld!'));
app.get('/wiki',(req,res)=>res.send('This is wiki page.'));
app.use((req,res)=>res.send('404-PageNotFound'));

Nota: abbiamo inserito la rotta 404 come ultima rotta mentre Express impila i percorsi in ordine e li elabora in sequenza per ogni richiesta.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow