Unterschied zwischen app.use und app.get in express.js


220

Ich bin etwas neu in express und node.js und kann den Unterschied zwischen app.use und app.get nicht herausfinden. Anscheinend können Sie beide zum Senden von Informationen verwenden. Beispielsweise:

app.use('/',function(req, res,next) {
    res.send('Hello');
    next();
});

scheint dasselbe zu sein:

app.get('/', function (req,res) {
   res.send('Hello');
});

1
Sieht so aus, als hätten Sie drei verschiedene Antworten erhalten, die alle etwas zum Thema beitragen :) Hier ist eine verwandte Frage stackoverflow.com/questions/11321635/…
Benjamin Gruenbaum

Ja, alle guten Antworten. Danke, ich werde mir das ansehen.
Andre Vorobyov

Antworten:


219

app.use()dient zum Binden von Middleware an Ihre Anwendung. Dies pathist ein " Mount " - oder " Präfix " -Pfad und beschränkt die Middleware darauf, nur auf alle angeforderten Pfade anzuwenden, die damit beginnen . Es kann sogar verwendet werden, um eine andere Anwendung einzubetten:

// subapp.js
var express = require('express');
var app = modules.exports = express();
// ...
// server.js
var express = require('express');
var app = express();

app.use('/subapp', require('./subapp'));

// ...

Wenn Sie /einen " Mount " -Pfad angeben, app.use()wird auf jeden Pfad reagiert, der mit beginnt /, und zwar alle und unabhängig vom verwendeten HTTP-Verb:

  • GET /
  • PUT /foo
  • POST /foo/bar
  • etc.

app.get()Andererseits ist es Teil des Anwendungsroutings von Express und dient zum Abgleichen und Behandeln einer bestimmten Route, wenn dies mit dem GETHTTP-Verb angefordert wird :

  • GET /

Und das äquivalente Routing für Ihr Beispiel app.use()wäre tatsächlich:

app.all(/^\/.*/, function (req, res) {
    res.send('Hello');
});

( Update: Versuch, die Unterschiede besser zu demonstrieren. )

Die Routing-Methoden, einschließlich app.get(), sind praktische Methoden, mit denen Sie Antworten auf Anforderungen genauer ausrichten können. Sie unterstützen auch Funktionen wie Parameter und next('route').

In jedem app.get()ist ein Aufruf an app.use(), so dass Sie all dies sicherlich app.use()direkt mit tun können. Dies erfordert jedoch häufig (wahrscheinlich unnötig) die Neuimplementierung verschiedener Mengen von Boilerplate-Code.

Beispiele:

  • Für einfache, statische Routen:

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

    vs.

    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      // ...
    });
  • Mit mehreren Handlern für dieselbe Route:

    app.get('/', authorize('ADMIN'), function (req, res) {
      // ...
    });

    vs.

    const authorizeAdmin = authorize('ADMIN');
    
    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      authorizeAdmin(req, res, function (err) {
        if (err) return next(err);
    
        // ...
      });
    });
  • Mit Parametern:

    app.get('/item/:id', function (req, res) {
      let id = req.params.id;
      // ...
    });

    vs.

    const pathToRegExp = require('path-to-regexp');
    
    function prepareParams(matches, pathKeys, previousParams) {
      var params = previousParams || {};
    
      // TODO: support repeating keys...
      matches.slice(1).forEach(function (segment, index) {
        let { name } = pathKeys[index];
        params[name] = segment;
      });
    
      return params;
    }
    
    const itemIdKeys = [];
    const itemIdPattern = pathToRegExp('/item/:id', itemIdKeys);
    
    app.use('/', function (req, res, next) {
      if (req.method !== 'GET') return next();
    
      var urlMatch = itemIdPattern.exec(req.url);
      if (!urlMatch) return next();
    
      if (itemIdKeys && itemIdKeys.length)
        req.params = prepareParams(urlMatch, itemIdKeys, req.params);
    
      let id = req.params.id;
      // ...
    });

Hinweis: Express' Implementierung dieser Funktionen in seiner enthalten sind Router, LayerundRoute .


3
Ein großes Lob für die Erwähnung eingebetteter Apps. Dies ist eine sehr praktische Möglichkeit, Express-Middleware zu organisieren.
wprl

4
Ist es fair zu sagen, dass app.use alles kann, was app.get, app.post, app.put tut, aber nicht umgekehrt?
Ngungo

6
immer noch schwer zu verstehen.
Jeb50

1
Es ist gut zu wissen , was die Verwendung und bekommen sind für , aber niemand hat eine große Aufgabe zu erklären , wie sie anders funktionieren. Soweit ich das beurteilen kann, werden alle .use-Handler zuerst ausgeführt, und .use stimmt mit jedem Pfad überein, der mit dem angegebenen Pfad beginnt (dh .use ('/', ...) und .get ('/ *', ...). ) würde den gleichen Pfaden entsprechen). Für mich ist es einfacher, die Gesamtkonzepte zu verstehen, wenn ich die beweglichen Teile sehen kann.
Snarf

2
Ich denke, es ist erwähnenswert, dass diese Antwort alt und veraltet ist. Zum Datum meines Kommentars benötigen Sie path-to-regexpnichts mehr und Sie können Routenparameter direkt im ersten Argument der useMethode verwenden.
Vdegenne

50

app.use ist die "Lower Level" -Methode von Connect, dem Middleware-Framework, von dem Express abhängt.

Hier ist meine Richtlinie:

  • Verwenden app.getSie diese Option, wenn Sie eine GET-Methode verfügbar machen möchten.
  • Verwenden app.useSie diese Option, wenn Sie Middleware hinzufügen möchten (einen Handler für die HTTP-Anforderung, bevor sie zu den in Express eingerichteten Routen gelangt) oder wenn Sie Ihre Routen modular gestalten möchten (z. B. eine Reihe von Routen verfügbar machen möchten) von einem npm-Modul, das andere Webanwendungen verwenden könnten).

Aber wenn mir die Methode egal ist, kann ich sie verwenden app.use, um einige Routen zu handhaben? Oder wir sollten niemals app.usefür das Routing verwenden.
Elemento0

Sie können app.use verwenden, um Ihre Routen in separate Dateien zu verschieben. Benutzer.js, Gebäude.js
Rob Angelier

1
Obwohl die eine Antwort darüber viel mehr UP / AGREE gesammelt hat, übersetzt Ihre Antwort anspruchsvolle Dinge, einschließlich Middleware, in ein paar einfache Wörter, Kudo.
Jeb50

50

Einfach app.use bedeutet "Bei ALLEN Anfragen
ausführen ". App.get bedeutet "Bei einer GET-Anfrage für die angegebene URL ausführen".


Es ist nicht so einfach. Lesen Sie andere Antworten.
David Lopez

28

app.getwird aufgerufen, wenn die HTTP-Methode auf gesetzt ist GET, während app.usesie unabhängig von der HTTP-Methode aufgerufen wird, und definiert daher eine Ebene, die über allen anderen RESTful-Typen liegt, auf die Sie mit den Express-Paketen zugreifen können.


19

Unterschied zwischen app.use& app.get:

app.use → Es wird im Allgemeinen zum Einführen von Middleware in Ihre Anwendung verwendet und kann alle Arten von HTTP-Anforderungen verarbeiten.

app.get → Es ist nur für die Verarbeitung von GET HTTP-Anforderungen vorgesehen.

Nun gibt es eine Verwechslung zwischen app.use& app.all. Zweifellos haben sie eines gemeinsam: Beide können alle Arten von HTTP-Anforderungen verarbeiten. Es gibt jedoch einige Unterschiede, die uns empfehlen, app.use für Middleware und app.all für die Routenbehandlung zu verwenden.

  1. app.use()→ Es dauert nur einen Rückruf.
    app.all()→ Es können mehrere Rückrufe erforderlich sein.

  2. app.use()wird nur sehen, ob die URL mit dem angegebenen Pfad beginnt.
    Aber, app.all()wird den vollständigen Pfad entspricht.

Beispielsweise,

app.use( "/book" , middleware);
// will match /book
// will match /book/author
// will match /book/subject

app.all( "/book" , handler);
// will match /book
// won't match /book/author   
// won't match /book/subject    

app.all( "/book/*" , handler);
// won't match /book        
// will match /book/author
// will match /book/subject
  1. next()rufen Sie innerhalb der app.use()entweder die nächste Middleware oder jede Route - Handler aufrufen, aber next()Anruf innen app.all()wird die nächste Route Handler (aufrufen app.all(), app.get/post/put...etc.) nur. Wenn danach Middleware vorhanden ist, wird diese übersprungen. Es ist daher ratsam, alle Middlewares immer über den Routenführern zu platzieren.

1
Ihr Punkt 3 scheint in Express 4.16 nicht zuzutreffen. Wenn Sie next()innerhalb von app.all('/*', ...)will aufrufen, wird in der Tat ein app.use('/', ...)späterer Vorgang in der Datei ausgeführt. Vielleicht habe ich dich dort falsch verstanden. Ansonsten sehr hilfreiche Erklärung.
BeetleJuice

In 4.17 beobachtete ich dasselbe wie @BeetleJuice
David Lopez

4

Zusätzlich zu den obigen Erklärungen erlebe ich Folgendes:

app.use('/book', handler);  

stimmt mit allen Anfragen überein, die mit '/ book' als URL beginnen. es passt also auch zu '/ book / 1' oder '/ book / 2'

app.get('/book')  

Entspricht nur der GET-Anforderung mit der genauen Übereinstimmung . URLs wie '/ book / 1' oder '/ book / 2' werden nicht verarbeitet.

Wenn Sie also einen globalen Handler benötigen, der alle Ihre Routen verarbeitet, app.use('/')ist dies die Option. app.get('/')behandelt nur die Root-URL.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.