Differenza tra app.all ('*') e app.use ('/')


121

C'è un'utile differenza tra app.all('*', ... )e app.use('/', ...)in Node.JS Express?

Risposte:


119

Nella maggior parte dei casi funzionerebbero in modo equivalente. La differenza più grande è l'ordine in cui verrà applicato il middleware:

  • app.all() si collega al router dell'applicazione, quindi viene utilizzato ogni volta che viene raggiunto il middleware app.router (che gestisce tutti i percorsi del metodo ... GET, POST, ecc.).

AVVISO: app.router è stato deprecato in express 4.x

  • app.use()si collega allo stack middleware principale dell'applicazione, quindi viene utilizzato nell'ordine specificato dal middleware. ad esempio, se lo metti per primo, sarà la prima cosa da eseguire. Se lo metti per ultimo (dopo il router), di solito non verrà eseguito affatto.

Di solito, se vuoi fare qualcosa a livello globale su tutti i percorsi, app.use () è l'opzione migliore. Inoltre, ha meno possibilità di bug futuri, poiché Express 0.4 probabilmente lascerà cadere il router implicito (il che significa che la posizione del router nel middleware sarà più importante di quanto non sia adesso, dal momento che tecnicamente non devi nemmeno usarlo proprio adesso).


15
Questo vale ancora dopo Express 4.x? app.router è stato rimosso.
ruffrey

1
Puoi usare next("route")con app.all, ma non con app.use.
Jozef Mikušinec

@JozefMikusinec Documentation sembra suggerire diversamente ... expressjs.com/en/guide/writing-middleware.html
musicin3d

Il tuo link non menziona il prossimo ('route'), ma ho guardato l'API, hai ragione.
Jozef Mikušinec

2
@ musicin3d Ho fatto ulteriori ricerche e ho trovato questo problema di GitHub , che conferma che "next () e next ('route') non hanno differenze con app.use" (citazione). Dovrebbero cambiare i documenti.
Jozef Mikušinec

87

app.use accetta solo una funzione di callback ed è pensato per il middleware. Il middleware di solito non gestisce la richiesta e la risposta, (tecnicamente possono) elaborano solo i dati di input e li consegnano al gestore successivo in coda.

app.use([path], function)

app.all accetta più callback ed è pensato per il routing. con più callback puoi filtrare le richieste e inviare risposte. È spiegato in Filtri su express.js

app.all(path, [callback...], callback)

app.use vede solo se l'URL inizia con il percorso specificato

app.use( "/product" , mymiddleware);
// will match /product
// will match /product/cool
// will match /product/foo

app.all corrisponderà al percorso completo

app.all( "/product" , handler);
// will match /product
// won't match /product/cool   <-- important
// won't match /product/foo    <-- important

app.all( "/product/*" , handler);
// won't match /product        <-- Important
// will match /product/
// will match /product/cool
// will match /product/foo

17
Almeno nella v4, app.use accetta una o più funzioni middleware, non "solo una".
Jess Austin

2
app.use vede solo se l'URL inizia con il percorso specificato; app.all corrisponderà al percorso completo. questa è la differenza principale.
meizilp

@frogcjn no, non dovrebbe in quanto ignora * e / nella mia domanda.
ostergaard

15
  • app.use:

    1. iniettare middlware al front controller configurando ad esempio: header, cookie, sessioni, ecc.
    2. deve essere scritto prima dell'app [http_method] altrimenti non verrà eseguito.
    3. diverse chiamate vengono elaborate nell'ordine di scrittura
  • app.all:

    1. (come l'app [http_method]) viene utilizzato per configurare i controller delle rotte
    2. "all" significa che si applica a tutti i metodi http.
    3. diverse chiamate vengono elaborate nell'ordine di scrittura

Guarda questo esempio di codice expressJs:

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

app.use(function frontControllerMiddlewareExecuted(req, res, next){
  console.log('(1) this frontControllerMiddlewareExecuted is executed');
  next();
});

app.all('*', function(req, res, next){
  console.log('(2) route middleware for all method and path pattern "*", executed first and can do stuff before going next');
  next();
});

app.all('/hello', function(req, res, next){
  console.log('(3) route middleware for all method and path pattern "/hello", executed second and can do stuff before going next');
  next();
});

app.use(function frontControllerMiddlewareNotExecuted(req, res, next){
  console.log('(4) this frontControllerMiddlewareNotExecuted is not executed');
  next();
});

app.get('/hello', function(req, res){
  console.log('(5) route middleware for method GET and path patter "/hello", executed last and I do my stuff sending response');
  res.send('Hello World');
});

app.listen(80);

Ecco il registro quando si accede alla route "/ hello":

(1) this frontControllerMiddlewareExecuted is executed
(2) route middleware for all method and path pattern "*", executed first and can do stuff before going next
(3) route middleware for all method and path pattern "/hello", executed second and can do stuff before going next
(5) route middleware for method GET and path patter "/hello", executed last and I do my stuff sending response

6
Dopo aver eseguito questo esempio alla lettera su express 4.x, vengono effettivamente eseguiti tutti e 5 in ordine. Ciò è probabilmente dovuto ai cambiamenti in express nei quasi 3 anni da quando è stato scritto, ma ho solo pensato di aggiungerlo per chiarezza.
Nathan Wiebe

11

Con app.use(), il percorso "mount" viene rimosso e non è visibile alla funzione middleware:

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

Le funzioni middleware montate ( express.static) non vengono invocate a meno che non req.urlcontenga questo prefisso ( /static), a quel punto viene rimosso quando viene richiamata la funzione.

Con app.all(), non c'è quel comportamento.


La domanda chiede esplicitamente solo su app.use ('/', ...).
ostergaard

Questa è la risposta corretta alla domanda che è ancora vera nel 2018! Un middleware può essere montato anche con all () ... l'unica differenza è che il percorso di montaggio viene rimosso durante l'esecuzione del middleware.
Xatian il

4

Sì, app.all()viene chiamato quando un particolare URI viene richiesto con qualsiasi tipo di metodo di richiesta (POST, GET, PUT o DELETE)

D'altra parte app.use()viene utilizzato per qualsiasi middleware che potresti avere e monta su un prefisso di percorso e verrà chiamato ogni volta che viene richiesto un URI sotto quella rotta.

Ecco la documentazione per app.all e app.use .


grazie ma penso che ti sei perso il carattere jolly app.all e il percorso di root app.use che li rendono praticamente esattamente la stessa cosa, vero? Tranne che app.all può accettare una serie di callback e app.use può prenderne solo uno, giusto?
ostergaard

1

Due differenze tutte le risposte di cui sopra non sono metion.

Il primo: app.allaccetta una regex come parametro del percorso. app.useNON accetta una regex.

Il secondo: app.all(path,handler)o app[method](path,handler), il gestore pathdeve essere uguale a tutti path . Questo significa che il percorso dell'app [metodo] è completo.

app.use(path,hanlder), se il percorso di utilizzo è completo, il percorso dell'hanlder deve essere "/". Se il percorso di utilizzo è l'inizio del percorso completo, il percorso del gestore deve essere il resto del percorso completo.

 app.use('/users', users);

  //users.js:  the handler will be called when matchs `/user/` path
      router.get('/', function(req, res, next) {
      res.send('respond with a resource');
    });
  // others.js: the handler will be called when matchs `/users/users` path
      router.get('/users', function(req, res, next) {
      res.send('respond with a resource');
    });

app.all('/users', users);

//others.js: the handler wil be called when matchs `/`path
router.get('/', function(req, res, next) {
     res.send('respond with a resource');
});
//users.js: the handler will be called when matchs `/users` path
router.get('/users', function(req, res, next) {
    res.send('respond with a resource');
 });

0

Ci sono due differenze principali:

1. pattern matching (risposta data da Palani)
2. next(route)non funzionerà all'interno del corpo della funzione del middleware caricato usando app.use. Questo è indicato nel link dai documenti:

NOTE: next('route') will work only in middleware functions that were loaded by using the app.METHOD() or router.METHOD() functions.

Collegamento: http://expressjs.com/en/guide/using-middleware.html

L'effetto di lavoro di next('route')può essere visto dal seguente esempio:

app.get('/',
(req,res,next)=>{console.log("1");
next(route); //The code here skips ALL the following middlewares
}
(req,res,next)=>{next();}, //skipped
(req,res,next)=>{next();}  //skipped
);

//Not skipped
app.get('/',function(req,res,next){console.log("2");next();});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.