Unterschied zwischen app.all ('*') und app.use ('/')

121

Gibt es einen nützlichen Unterschied zwischen app.all('*', ... )und app.use('/', ...)in Node.JS Express?

ostergaard
quelle

Antworten:

119

In den meisten Fällen würden sie gleichwertig arbeiten. Der größte Unterschied besteht in der Reihenfolge, in der die Middleware angewendet wird:

  • app.all() Wird an den Router der Anwendung angehängt und wird daher immer dann verwendet, wenn die Middleware app.router erreicht wird (die alle Methodenrouten verarbeitet ... GET, POST usw.).

HINWEIS: app.router ist in Express 4.x veraltet

  • app.use()Wird an den Haupt-Middleware-Stack der Anwendung angehängt, sodass er in der von der Middleware angegebenen Reihenfolge verwendet wird. Wenn Sie es beispielsweise an die erste Stelle setzen, wird es als erstes ausgeführt. Wenn Sie es zuletzt (nach dem Router) setzen, wird es normalerweise überhaupt nicht ausgeführt.

Wenn Sie global etwas mit allen Routen tun möchten, ist normalerweise app.use () die bessere Option. Außerdem besteht eine geringere Wahrscheinlichkeit für zukünftige Fehler, da Express 0.4 wahrscheinlich den impliziten Router fallen lässt (was bedeutet, dass die Position des Routers in der Middleware wichtiger ist als jetzt, da Sie ihn technisch nicht einmal verwenden müssen jetzt sofort).

hunterloftis
quelle
15
Gilt dies auch nach Express 4.x? app.router wurde entfernt.
Ruffrey
1
Sie können next("route")mit verwenden app.all, aber nicht mit app.use.
Jozef Mikušinec
@ JozefMikusinec Dokumentation scheint etwas anderes vorzuschlagen ... expressjs.com/en/guide/writing-middleware.html
musicin3d
Ihr Link erwähnt nicht weiter ('Route'), aber ich habe mir die API angesehen, Sie haben Recht.
Jozef Mikušinec
2
@ musicin3d Ich habe weiter recherchiert und dieses GitHub-Problem gefunden , das bestätigt, dass "next () und next ('route') keinen Unterschied zu app.use haben" (Zitat). Sie sollten die Dokumente ändern.
Jozef Mikušinec
87

app.use verwendet nur eine Rückruffunktion und ist für Middleware gedacht. Middleware verarbeitet normalerweise keine Anforderungen und Antworten (technisch können sie dies), sondern verarbeitet nur Eingabedaten und übergibt sie an den nächsten Handler in der Warteschlange.

app.use([path], function)

app.all nimmt mehrere Rückrufe entgegen und ist für das Routing gedacht. Mit mehreren Rückrufen können Sie Anforderungen filtern und Antworten senden. Es wird in Filter auf express.js erklärt

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

app.use sieht nur, ob die URL mit dem angegebenen Pfad beginnt

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

app.all entspricht dem vollständigen Pfad

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
quelle
17
Zumindest in Version 4 übernimmt app.use eine oder mehrere Middleware-Funktionen, nicht "nur eine".
Jess Austin
2
app.use sieht nur, ob die URL mit dem angegebenen Pfad beginnt; app.all stimmt mit dem vollständigen Pfad überein. Das ist der Hauptunterschied.
Meizilp
@frogcjn nein sollte es nicht, da es das * und / oder in meiner Frage ignoriert.
Ostergaard
15
  • app.use:

    1. Injizieren Sie Middlware in Ihren Front-Controller, indem Sie beispielsweise Folgendes konfigurieren: Header, Cookies, Sitzungen usw.
    2. muss vor app [http_method] geschrieben werden, sonst wird es nicht ausgeführt.
    3. Mehrere Anrufe werden in der Reihenfolge des Schreibens bearbeitet
  • entsetzen:

    1. (wie App [http_method]) wird zum Konfigurieren der Controller von Routen verwendet
    2. "all" bedeutet, dass es für alle http-Methoden gilt.
    3. Mehrere Anrufe werden in der Reihenfolge des Schreibens bearbeitet

Schauen Sie sich dieses ExpressJs-Codebeispiel an:

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);

Hier ist das Protokoll beim Zugriff auf die Route '/ hallo':

(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
daemon1981
quelle
6
Nachdem dieses Beispiel wörtlich in Express 4.x ausgeführt wurde, werden alle 5 nacheinander ausgeführt. Dies ist wahrscheinlich auf Änderungen im Express in den fast 3 Jahren seit dem Schreiben zurückzuführen, aber ich dachte nur, ich würde dies aus Gründen der Klarheit hinzufügen.
Nathan Wiebe
11

Mit app.use()wird der "Mount" -Pfad entfernt und ist für die Middleware-Funktion nicht sichtbar:

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

Bereitgestellte Middleware-Funktionen ( express.static) werden nur aufgerufen, wenn sie req.urldieses Präfix ( /static) enthalten. An diesem Punkt wird es beim Aufrufen der Funktion entfernt.

Mit app.all()gibt es kein solches Verhalten.

besser9
quelle
Die Frage bezieht sich explizit nur auf app.use ('/', ...).
Ostergaard
Dies ist die richtige Antwort auf die Frage, die 2018 noch wahr ist! Eine Middleware kann auch mit all () gemountet werden. Der einzige Unterschied besteht darin, dass der Mount-Pfad beim Ausführen der Middleware entfernt wird.
Xatian
4

Ja, app.all() wird aufgerufen, wenn ein bestimmter URI mit einer beliebigen Anforderungsmethode (POST, GET, PUT oder DELETE) angefordert wird.

Andererseits app.use() wird es für jede Middleware verwendet, die Sie möglicherweise haben, und es wird auf ein Pfadpräfix gemountet und wird jedes Mal aufgerufen, wenn eine URI unter dieser Route angefordert wird.

Hier ist die Dokumentation für app.all & app.use .

Gurpreet Singh
quelle
danke, aber ich denke, du hast den app.all-Platzhalter und den app.use-Stammpfad verpasst, wodurch sie ziemlich genau dasselbe sind, nicht wahr? Abgesehen davon, dass app.all eine Reihe von Rückrufen annehmen kann und app.use nur einen annehmen kann - richtig?
Ostergaard
1

Zwei Unterschiede, die alle oben genannten Antworten nicht erfüllen.

Der erste: app.allakzeptiert einen regulären Ausdruck als Pfadparameter . app.useakzeptiert KEINE Regex.

Der zweite: app.all(path,handler)oder app[method](path,handler), der Handler pathmuss für alle gleich sein path . Dies bedeutet, dass der Pfad von app [method] vollständig ist.

app.use(path,hanlder)Wenn der Pfad der Verwendung vollständig ist, muss der Pfad des Handers '/' sein. Wenn der Pfad der Verwendung der Anfang des vollständigen Pfads ist, muss der Handlerpfad der Rest des vollständigen Pfads sein.

 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
quelle
0

Es gibt zwei Hauptunterschiede:

1. Mustervergleich (Antwort von Palani)
2. next(route)Funktioniert nicht im Funktionskörper der mit geladenen Middleware app.use. Dies wird im Link aus den Dokumenten angegeben:

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

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

Der Arbeitseffekt von next('route')ist aus dem folgenden Beispiel ersichtlich:

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
quelle