Różnica między app.use i app.get w express.js


220

Jestem trochę nowy do wyrażenia i node.js i nie mogę zrozumieć różnicy między app.use i app.get. Wygląda na to, że możesz użyć obu z nich do wysyłania informacji. Na przykład:

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

wydaje się być taki sam:

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

1
Wygląda na to, że masz trzy różne odpowiedzi, z których wszystkie przyczyniają się do tematu :) Oto powiązane pytanie stackoverflow.com/questions/11321635/...
— Benjamin Gruenbaum

tak, wszystkie dobre odpowiedzi. Dzięki, spojrzę na to.
— Andre Vorobyov

Odpowiedzi:


219

app.use()jest przeznaczony do wiązania oprogramowania pośredniego z aplikacją. Jest pathto ścieżka „ montowania ” lub „ prefiksu ” i ogranicza oprogramowanie pośrednie do stosowania tylko do żądanych ścieżek, które zaczynają się od niego. Można go nawet użyć do osadzenia innej aplikacji:

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

// ...

Określając /jako ścieżkę „ mount ”, app.use()odpowie na każdą ścieżkę, która zaczyna się od /, które są wszystkie i niezależnie od użytego czasownika HTTP:

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

app.get(), z drugiej strony, jest częścią routingu aplikacji Express i jest przeznaczony do dopasowywania i obsługi określonej trasy na żądanie GETczasownika HTTP:

  • GET /

Odpowiednim routingiem dla Twojego przykładu app.use()byłoby:

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

( Aktualizacja: Próba lepszego wykazania różnic. )

Metody routingu, w tym app.get(), są wygodnymi metodami, które pomagają precyzyjniej dopasowywać odpowiedzi na żądania. Dodają także obsługę takich funkcji, jak parametry i next('route').

Wewnątrz każdego app.get()jest wezwanie do app.use(), więc z pewnością możesz to wszystko zrobić app.use()bezpośrednio. Ale zrobienie tego często będzie wymagało (prawdopodobnie niepotrzebnie) zaimplementowania różnych ilości kodu płyty głównej.

Przykłady:

  • W przypadku prostych, statycznych tras:

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

    vs.

    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      // ...
    });
  • Z wieloma modułami obsługi dla tej samej trasy:

    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);
    
        // ...
      });
    });
  • Z parametrami:

    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;
      // ...
    });

Uwaga: wdrożenie Express' z tych funkcji są zawarte w jego Router, LayeriRoute .


3
Wyrazy uznania za wspomnienie o aplikacjach osadzonych. Jest to bardzo przydatny sposób organizowania ekspresowego oprogramowania pośredniego.
— wprl

4
Czy można powiedzieć, że app.use może zrobić wszystko z app.get, app.post, app.put, ale nie odwrotnie?
— ngungo

6
wciąż trudny do zrozumienia.
— Jeb50

1
Dobrze jest wiedzieć, po co i dostać się do , ale nikt nie robi świetną robotę, wyjaśniając, w jaki sposób działać w różny sposób. Z tego, co mogę zebrać, wszystkie programy obsługi .use uruchamiane są jako pierwsze, a .use pasuje do dowolnej ścieżki, która zaczyna się od określonej ścieżki (tj. .Use ('/', ...) i .get ('/ *', ... ) pasują do tych samych ścieżek). Dla mnie łatwiej jest zrozumieć ogólne koncepcje, kiedy widzę ruchome części.
— snarf

2
Myślę, że WARTO ZWRÓCIĆ UWAGĘ, że ta odpowiedź jest stara i nieaktualna, ponieważ na dzień mojego komentarza już nie potrzebujesz path-to-regexpani nic i możesz użyć parametrów trasy bezpośrednio w pierwszym argumencie usemetody.
— vdegenne

50

app.use jest metodą „niższego poziomu” firmy Connect, frameworka oprogramowania pośredniego, od którego zależy Express.

Oto moja wskazówka:

  • Użyj, app.getjeśli chcesz ujawnić metodę GET.
  • Użyj, app.usejeśli chcesz dodać oprogramowanie pośrednie (moduł obsługi żądania HTTP, zanim dotrze ono do tras skonfigurowanych w Express) lub jeśli chcesz, aby Twoje trasy były modułowe (na przykład ujawnij zestaw tras z modułu npm, z którego mogłyby korzystać inne aplikacje internetowe).

Ale jeśli nie obchodzi mnie metoda, mogę użyć app.useniektórych tras? Lub nigdy nie powinniśmy używać app.usedo routingu.
— Elemento0,

Możesz użyć app.use, aby przenieść swoje trasy do oddzielnych plików eq. users.js, buildings.js
— Rob Angelier

1
chociaż jedna z powyższych odpowiedzi zebrała więcej UP / AGREE, twoja odpowiedź przekłada wyrafinowaną rzecz, w tym Middleware, na kilka prostych słów, kudo.
— Jeb50

50

Po prostu app.use oznacza „Uruchom to na WSZYSTKICH żądaniach”
app.get oznacza „Uruchom to na żądanie GET dla danego adresu URL”


To nie takie proste. Przeczytaj inne odpowiedzi.
— David Lopez

28

app.getjest wywoływany, gdy metoda HTTP jest ustawiona na GET, natomiast app.usejest wywoływana niezależnie od metody HTTP, a zatem definiuje warstwę, która jest na wierzchu wszystkich innych typów RESTful, do których dostęp mają pakiety ekspresowe.


19

Różnica między app.use& app.get:

app.use → Zasadniczo służy do wprowadzania oprogramowania pośredniego w aplikacji i może obsługiwać wszystkie typy żądań HTTP.

app.get → Służy tylko do obsługi żądań GET HTTP.

Teraz istnieje pomieszanie między app.use& app.all. Bez wątpienia jest w nich jedna wspólna cecha: obie mogą obsługiwać wszelkiego rodzaju żądania HTTP. Ale istnieją pewne różnice, które zalecają nam używanie app.use do oprogramowania pośredniego i app.all do obsługi tras.

  1. app.use()→ Zajmuje tylko jedno oddzwonienie.
    app.all()→ Może to obejmować wiele połączeń zwrotnych.

  2. app.use()zobaczy tylko, czy adres URL zaczyna się od określonej ścieżki.
    Ale app.all()dopasuje pełną ścieżkę.

Na przykład,

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()zadzwoń wewnątrz app.use()zadzwoni albo kolejnej warstwy pośredniej ani żadnej obsługi trasy, ale next()rozmowa wewnątrz app.all()wywoła kolejną obsługi trasy ( app.all(), app.get/post/put...etc.) tylko. Jeśli pojawi się jakieś oprogramowanie pośrednie, zostanie ono pominięte. Dlatego wskazane jest, aby umieścić wszystkie oprogramowanie pośrednie zawsze powyżej procedur obsługi trasy.

1
Twój punkt 3 wydaje się nie mieć zastosowania do Express 4.16. wywołanie next()wewnątrz app.all('/*', ...)spowoduje wykonanie app.use('/', ...)później w pliku. Może źle cię tam zrozumiałem. Bardzo pomocne wyjaśnienie inaczej.
— BeetleJuice

W 4.17 zaobserwowałem to samo, co @BeetleJuice
— David Lopez

4

Oprócz powyższych wyjaśnień, czego doświadczam:

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

dopasuje wszystkie żądania zaczynające się od „/ book” jako URL. więc pasuje również do „/ book / 1” lub „/ book / 2”

app.get('/book')  

dopasowuje tylko żądanie GET z dopasowaniem ścisłym . Nie obsługuje adresów URL takich jak „/ book / 1” lub „/ book / 2”

Tak więc, jeśli chcesz mieć globalny moduł obsługi, który obsługuje wszystkie twoje trasy, app.use('/')jest to opcja. app.get('/')obsłuży tylko główny adres URL.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.