Разница между app.use и app.get в express.js


220

Я новичок в выражениях и node.js и не могу понять разницу между app.use и app.get. Кажется, вы можете использовать их обоих для отправки информации. Например:

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

кажется, так же, как это:

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

1
Похоже, у вас есть три разных ответа, каждый из которых вносит свой вклад в тему :) Вот связанный вопрос stackoverflow.com/questions/11321635/…
Бенджамин Грюнбаум

да, все хорошие ответы. Спасибо, я посмотрю на это.
Андре Воробьев

Ответы:


220

app.use()предназначен для привязки промежуточного программного обеспечения к вашему приложению. Это путь path« mount » или « prefix », который ограничивает промежуточное программное обеспечение только для всех запрошенных путей, начинающихся с него. Он может даже использоваться для встраивания другого приложения:

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

// ...

Указывая путь /« монтирования », вы app.use()будете реагировать на любой путь, который начинается с /каждого из них, независимо от используемого глагола HTTP:

  • GET /
  • PUT /foo
  • POST /foo/bar
  • и т.п.

app.get()с другой стороны, является частью маршрутизации приложений Express и предназначена для сопоставления и обработки определенного маршрута при запросе с GETглаголом HTTP:

  • GET /

И эквивалентная маршрутизация для вашего примера app.use()будет:

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

( Обновление: попытка лучше продемонстрировать различия. )

Методы маршрутизации, в том числе app.get(), являются удобными методами, которые помогают вам более точно выровнять ответы на запросы. Они также добавляют поддержку таких функций, как параметры и next('route').

Внутри каждого app.get()есть вызов app.use(), так что вы можете сделать все это app.use()напрямую. Но для этого часто требуется (вероятно, излишне) переопределение различных объемов стандартного кода.

Примеры:

  • Для простых статических маршрутов:

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

    против

    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      // ...
    });
  • С несколькими обработчиками для одного маршрута:

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

    против

    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);
    
        // ...
      });
    });
  • С параметрами:

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

    против

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

Примечание: реализация Express' этих функций содержатся в его Router, LayerиRoute .


3
Слава за упоминание встроенных приложений. Это очень удобный способ организации экспресс-промежуточного программного обеспечения.
wprl

4
Справедливо ли сказать, что app.use может делать все, что делает каждый из app.get, app.post, app.put, но не наоборот?
ngungo

6
все еще трудно понять.
Jeb50

1
Это хорошо , чтобы знать , что такое использование и получить в течение , но никто не делает большую работу, объясняя , как они функционируют по- разному. Из того, что я могу собрать, все обработчики .use запускаются первыми, а .use соответствует любому пути, начинающемуся с указанного пути (т.е. .use ('/', ...) и .get ('/ *', ... ) будет соответствовать тем же путям). Для меня легче понять общие концепции, когда я вижу движущиеся части.
snarf

2
Я думаю, что стоит отметить, что этот ответ является устаревшим и устаревшим, поскольку на момент моего комментария вам больше не нужно path-to-regexpили что-то еще, и вы можете использовать параметры маршрута непосредственно в первом аргументе useметода.
августа

50

app.use это метод «нижнего уровня» Connect, от которого зависит промежуточное ПО, от которого зависит Express.

Вот мое руководство:

  • Используйте, app.getесли вы хотите выставить метод GET.
  • Используйте, app.useесли вы хотите добавить некоторое промежуточное программное обеспечение (обработчик для HTTP-запроса до того, как он прибудет на маршруты, которые вы настроили в Express), или если вы хотите сделать свои маршруты модульными (например, предоставить набор маршрутов). из модуля npm, который могут использовать другие веб-приложения).

Но если я не забочусь о методе, я могу использовать app.useдля обработки некоторых маршрутов? Или мы никогда не должны использовать app.useдля маршрутизации.
Elemento0

Вы можете использовать app.use для перемещения ваших маршрутов в отдельные файлы. users.js, Buildings.js
Роб Анджельер

1
хотя один ответ выше этого собрал гораздо больше UP / AGREE, ваш ответ переводит сложные вещи, включая Middleware, в несколько простых слов, kudo.
Jeb50

50

Просто app.use означает «Запустить это по ВСЕМ запросам».
App.get означает «Запустить это по GET-запросу для данного URL».


Это не так просто. Читайте другие ответы.
Дэвид Лопес

28

app.getвызывается, когда для HTTP-метода установлено значение GET, тогда как app.useвызывается независимо от метода HTTP и поэтому определяет уровень, который находится поверх всех других типов RESTful, к которым экспресс-пакеты предоставляют вам доступ.


19

Разница между app.use& app.get:

app.use → Обычно он используется для внедрения промежуточного программного обеспечения в вашем приложении и может обрабатывать все типы HTTP-запросов.

app.get → Это только для обработки запросов GET HTTP.

Теперь между app.use& app.all. Несомненно, в них есть одна общая черта: оба могут обрабатывать все виды HTTP-запросов. Но есть некоторые отличия, которые рекомендуют нам использовать app.use для middlewares и app.all для обработки маршрутов.

  1. app.use()→ Требуется только один обратный вызов.
    app.all()→ Это может занять несколько обратных вызовов.

  2. app.use()будет только видеть, начинается ли URL с указанного пути.
    Но, app.all()будет соответствовать полный путь.

Например,

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()вызов внутри app.use()будет вызывать либо следующее промежуточное программное обеспечение, либо любой обработчик маршрута, но next()вызов внутри app.all()вызовет только следующий обработчик маршрута ( app.all()и app.get/post/put...т. д.). Если после этого будет какое-либо промежуточное программное обеспечение, оно будет пропущено. Поэтому рекомендуется размещать все промежуточные программы всегда над обработчиками маршрутов.

1
Ваш пункт 3, кажется, не относится к Express 4.16. вызов next()внутри app.all('/*', ...)будет на самом деле выполнить app.use('/', ...)позже в файле. Может быть, я неправильно понял вас там. Очень полезное объяснение в противном случае.
BeetleJuice

В 4.17 я наблюдал то же, что и @BeetleJuice
Дэвид Лопес

4

Помимо приведенных выше объяснений, что я испытываю:

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

будет соответствовать всем запросам, начинающимся с '/ book' в качестве URL. так что это также соответствует '/ book / 1' или '/ book / 2'

app.get('/book')  

соответствует только GET-запросу с точным соответствием . Он не будет обрабатывать URL-адреса, такие как «/ book / 1» или «/ book / 2»

Так что, если вам нужен глобальный обработчик, который обрабатывает все ваши маршруты, тогда app.use('/')это вариант. app.get('/')будет обрабатывать только корневой URL.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.