Différence entre app.all ('*') et app.use ('/')

121

Existe-t-il une différence utile entre app.all('*', ... )et app.use('/', ...)dans Node.JS Express?

Ostergaard
la source

Réponses:

119

Dans la plupart des cas, ils fonctionneraient de manière équivalente. La plus grande différence est l'ordre dans lequel le middleware serait appliqué:

  • app.all() s'attache au routeur de l'application, il est donc utilisé chaque fois que le middleware app.router est atteint (qui gère toutes les routes de méthode ... GET, POST, etc.).

AVIS: app.router est obsolète dans express 4.x

  • app.use()s'attache à la pile middleware principale de l'application, il est donc utilisé dans l'ordre spécifié par le middleware. par exemple, si vous le mettez en premier, ce sera la première chose à exécuter. Si vous le mettez en dernier (après le routeur), il ne sera généralement pas exécuté du tout.

Habituellement, si vous voulez faire quelque chose de manière globale sur toutes les routes, app.use () est la meilleure option. En outre, il a moins de chance de futurs bogues, car express 0.4 supprimera probablement le routeur implicite (ce qui signifie que la position du routeur dans le middleware sera plus importante qu'elle ne l'est actuellement, car techniquement vous n'avez même pas à l'utiliser. maintenant).

Hunterloftis
la source
15
Cela s'applique-t-il toujours après Express 4.x? app.router a été supprimé.
ruffrey
1
Vous pouvez utiliser next("route")avec app.all, mais pas avec app.use.
Jozef Mikušinec
@JozefMikusinec La documentation semble suggérer le contraire ... expressjs.com/en/guide/writing-middleware.html
musicin3d
Votre lien ne mentionne pas la prochaine ('route'), mais j'ai regardé l'API, vous avez raison.
Jozef Mikušinec
2
@ musicin3d J'ai fait des recherches plus poussées et j'ai trouvé ce problème GitHub , qui confirme que "next () et next ('route') n'ont aucune différence avec app.use" (citation). Ils devraient changer les documents.
Jozef Mikušinec
87

app.use ne prend qu'une seule fonction de rappel et est destiné au middleware. L'intergiciel ne gère généralement pas les demandes et les réponses, (techniquement, ils le peuvent), ils ne traitent que les données d'entrée et les remettent au gestionnaire suivant dans la file d'attente.

app.use([path], function)

app.all prend plusieurs rappels et est destiné au routage. avec plusieurs rappels, vous pouvez filtrer les demandes et envoyer des réponses. C'est expliqué dans Filtres sur express.js

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

app.use voit uniquement si l'URL commence par le chemin spécifié

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

app.all correspondra au chemin complet

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
Palani
la source
17
Au moins dans la v4, app.use prend une ou plusieurs fonctions middleware, pas "une seule".
Jess Austin
2
app.use ne voit que si l'URL commence par le chemin spécifié; app.all correspondra au chemin complet. c'est la principale différence.
meizilp
@frogcjn non il ne devrait pas car il ignore le * et / dans ma question.
ostergaard
15
  • app.use:

    1. injectez un middlware sur votre contrôleur frontal en configurant par exemple: en-tête, cookies, sessions, etc.
    2. doit être écrit avant app [http_method] sinon il ne sera pas exécuté.
    3. plusieurs appels sont traités dans l'ordre d'écriture
  • épouvanter:

    1. (comme l'application [http_method]) est utilisé pour configurer les contrôleurs des routes
    2. "all" signifie qu'il s'applique à toutes les méthodes http.
    3. plusieurs appels sont traités dans l'ordre d'écriture

Regardez cet exemple de code 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);

Voici le journal lors de l'accès à la route '/ bonjour':

(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
démon1981
la source
6
Après avoir exécuté cet exemple textuellement sur express 4.x, il exécute en fait les 5 dans l'ordre. Cela est probablement dû à des changements dans l'express dans les presque 3 ans depuis que cela a été écrit, mais je pensais juste que j'ajouterais ceci pour plus de clarté.
Nathan Wiebe
11

Avec app.use(), le chemin "mount" est dépouillé et n'est pas visible pour la fonction middleware:

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

Les fonctions middleware montées ( express.static) ne sont pas appelées sauf si le req.urlcontient ce préfixe ( /static), auquel point il est supprimé lorsque la fonction est appelée.

Avec app.all(), il n'y a pas ce comportement.

mieux9
la source
La question concerne explicitement app.use ('/', ...) uniquement.
ostergaard
C'est la bonne réponse à la question qui est toujours vraie en 2018! Un middleware peut également être monté avec all () ... la seule différence est que le chemin de montage est supprimé lors de l'exécution du middleware.
Xatian
4

Oui, app.all()est appelé lorsqu'un URI particulier est demandé avec n'importe quel type de méthode de requête (POST, GET, PUT ou DELETE)

D'autre part, il app.use()est utilisé pour tout middleware que vous pourriez avoir et il se monte sur un préfixe de chemin, et sera appelé à chaque fois qu'un URI sous cette route est demandé.

Voici la documentation pour app.all et app.use .

Gurpreet Singh
la source
merci mais je pense que vous avez manqué le joker app.all et le chemin racine app.use qui en font à peu près exactement la même chose, n'est-ce pas? Sauf que app.all peut prendre un éventail de rappels et app.use ne peut en prendre qu'un - non?
ostergaard
1

Deux différences, toutes les réponses ci-dessus ne se métissent pas.

Le premier: app.allaccepte une regex comme paramètre de chemin. app.usen'accepte PAS de regex.

Le second: app.all(path,handler)ou app[method](path,handler), celui du gestionnaire pathdoit être le même que celui de tous path . Le chemin de l'application [méthode] est terminé.

app.use(path,hanlder), si le chemin de l'utilisation est complet, le chemin du hanlder doit être '/'. Si le chemin de l'utilisation est le début du chemin complet, le chemin du gestionnaire doit être le reste du chemin complet.

 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');
 });
JackChouMine
la source
0

Il y a deux différences principales:

1. correspondance de modèle (réponse donnée par Palani)
2. next(route)ne fonctionnera pas dans le corps des fonctions du middleware chargé en utilisant app.use. Ceci est indiqué dans le lien de la documentation:

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

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

L'effet fonctionnel de next('route')peut être vu à partir de l'exemple suivant:

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();});
Ng Ju Ping
la source