Разница между app.all ('*') и app.use ('/')


Ответы:


119

В большинстве случаев они будут работать одинаково. Самая большая разница - это порядок, в котором будет применяться промежуточное ПО:

  • app.all() подключается к маршрутизатору приложения, поэтому он используется всякий раз, когда достигается промежуточное ПО app.router (которое обрабатывает все маршруты методов ... GET, POST и т. д.).

ВНИМАНИЕ: app.router устарел в express 4.x

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

Обычно, если вы хотите сделать что-то глобально для всех маршрутов, app.use () - лучший вариант. Кроме того, у него меньше шансов на будущие ошибки, так как Express 0.4, вероятно, отбросит неявный маршрутизатор (это означает, что положение маршрутизатора в промежуточном программном обеспечении будет более важным, чем сейчас, поскольку вам технически даже не нужно его использовать. сейчас).


15
Это все еще актуально после Express 4.x? app.router был удален.
ruffrey

1
Вы можете использовать next("route")с app.all, но не с app.use.
Jozef Mikušinec

@JozefMikusinec Документация, кажется, предполагает иное ... expressjs.com/en/guide/writing-middleware.html
musicin3d

В вашей ссылке не упоминается следующий («маршрут»), но я посмотрел на API, вы правы.
Jozef Mikušinec

2
@ musicin3d Я исследовал дальше и нашел эту проблему на GitHub , которая подтверждает, что «next () и next ('route') не имеют разницы с app.use» (цитата). Они должны изменить документы.
Jozef Mikušinec

87

app.use принимает только одну функцию обратного вызова и предназначена для промежуточного программного обеспечения. По промежуточного слоя обычно не обрабатываются запросы и ответы (технически они могут), они просто обрабатывают входные данные и передают их следующему обработчику в очереди.

app.use([path], function)

app.all принимает несколько обратных вызовов и предназначен для маршрутизации. с несколькими обратными вызовами вы можете фильтровать запросы и отправлять ответы. Это объясняется в фильтрах на express.js

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

app.use только видит, начинается ли url с указанного пути

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

app.all будет соответствовать полному пути

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

17
По крайней мере, в версии 4 app.use принимает одну или несколько функций промежуточного программного обеспечения, а не «только одну».
Джесс Остин

2
app.use только проверяет, начинается ли url с указанного пути; app.all будет соответствовать полному пути. это главное отличие.
meizilp

@frogcjn нет, этого не должно быть, поскольку он игнорирует * и / в моем вопросе.
ostergaard 05

15
  • app.use:

    1. внедрить промежуточное программное обеспечение в ваш фронт-контроллер, настроив, например, заголовок, файлы cookie, сеансы и т. д.
    2. должен быть написан перед app [http_method], иначе он не будет выполнен.
    3. несколько звонков обрабатываются в порядке записи
  • app.all:

    1. (например, приложение [http_method]) используется для настройки контроллеров маршрутов.
    2. «все» означает, что он применяется ко всем методам http.
    3. несколько звонков обрабатываются в порядке записи

Взгляните на этот пример кода 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);

Вот журнал доступа к маршруту '/ hello':

(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

6
После дословного выполнения этого примера в Express 4.x он фактически выполняет все 5 по порядку. Вероятно, это связано с изменениями в экспрессе за почти 3 года с момента написания, но я просто подумал, что добавлю это для ясности.
Натан Вибе

11

С app.use(), путь "монтирования" удаляется и не отображается для функции промежуточного слоя:

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

Смонтированные функции промежуточного программного обеспечения ( express.static) не вызываются, если они не req.urlсодержат этот префикс ( /static), после чего он удаляется при вызове функции.

Причём app.all(), нет такого поведения.


Вопрос явно задает только app.use ('/', ...).
ostergaard

Это правильный ответ на вопрос, который актуален и в 2018 году! Промежуточное ПО также может быть смонтировано с помощью all () ... с той лишь разницей, что путь монтирования удаляется при выполнении промежуточного программного обеспечения.
Xatian

4

Да, app.all()вызывается, когда конкретный URI запрашивается с помощью любого типа метода запроса (POST, GET, PUT или DELETE)

С другой стороны app.use(), используется для любого промежуточного программного обеспечения, которое у вас может быть, и оно монтируется на префикс пути и будет вызываться каждый раз, когда запрашивается URI для этого маршрута.

Вот документация для app.all и app.use .


спасибо, но я думаю, вы пропустили подстановочный знак app.all и корневой путь app.use, которые делают их почти одинаковыми, не так ли? За исключением того, что app.all может принимать массив обратных вызовов, а app.use может принимать только один, верно?
ostergaard 02

1

Два различия во всех приведенных выше ответах не упоминаются.

Первый: app.allпринимает регулярное выражение в качестве параметра пути. app.useНЕ принимает регулярное выражение.

Второй: app.all(path,handler)или app[method](path,handler), обработчик pathдолжен быть одинаковым для всех path . Таким образом, путь app [method] завершен.

app.use(path,hanlder), если путь использования завершен, путь обработчика должен быть '/'. Если путь использования является началом полного пути, путь обработчика должен быть оставшейся частью полного пути.

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

0

Есть два основных отличия:

1. сопоставление с образцом (ответ дал Палани)
2. next(route)не будет работать внутри тела функции промежуточного программного обеспечения, загруженного с использованием app.use. Об этом говорится в ссылке из документов:

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

Ссылка: http://expressjs.com/en/guide/using-middleware.html

Рабочий эффект next('route')можно увидеть на следующем примере:

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();});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.