Різниця між app.all ('*') та app.use ('/')


Відповіді:


119

У більшості випадків вони працювали б рівномірно. Найбільша різниця - це порядок, в якому буде застосовано проміжне програмне забезпечення:

  • app.all() приєднується до маршрутизатора програми, тому він використовується, коли досягається середнє програмне забезпечення app.router (яке обробляє всі маршрути методів ... GET, POST тощо).

ПОВІДОМЛЕННЯ: app.router застарілий у виразі 4.x

  • app.use()додається до основного стека програмного забезпечення середнього програмного забезпечення, тому він використовується в порядку, визначеному середнім програмним забезпеченням. наприклад, якщо ви поставите його першим, це буде першим ділом. Якщо ви поставите його останньою (після маршрутизатора), вона зазвичай взагалі не працюватиме.

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


15
Це все ще застосовується після Express 4.x? app.router видалено
ruffrey

1
Ви можете використовувати next("route")з app.all, але не з app.use.
Юзеф Мікушинець

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

У вашому посиланні не згадується наступний ("маршрут"), але я переглянув API, ви маєте рацію.
Юзеф Мікушинець

2
@ musicin3d Я дослідив далі і виявив цю проблему GitHub , яка підтверджує, що "next () та next (" route ") не мають різниці для app.use" (цитата). Вони повинні змінити документи.
Юзеф Мікушинець

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
Принаймні в v4, app.use приймає одну або кілька функцій проміжного програмного забезпечення, а не "лише одну".
Джесс Остін

2
app.use бачить лише, чи URL-адреса починається із вказаного шляху; app.all відповідатиме повному шляху. це головна відмінність.
meizilp

@frogcjn ні, не слід, оскільки він ігнорує * та / у моєму запитанні.
ostergaard

15
  • app.use:

    1. введіть середнє програмне забезпечення у ваш передній контролер, налаштувавши, наприклад: заголовок, файли cookie, сесії тощо
    2. повинні бути написані перед додатком [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);

Ось журнал під час доступу до маршруту "/ привіт":

(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 в порядку. Це, мабуть, пов’язано із змінами експресів майже за три роки, відколи це було написано, але я просто думав, що додам це для наочності.
Натан Вібе

11

З app.use(), шлях "кріплення" позбавлений і не видно функції проміжного програмного забезпечення:

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

Функції встановленого посередництва ( express.static) не викликаються, якщо не req.urlмістить цей префікс ( /static), в який момент він знімається, коли функція викликається.

З app.all(), такої поведінки немає.


Питання прямо задається лише щодо app.use ('/', ...).
ostergaard

Це правильна відповідь на питання, яке все ще актуально у 2018 році! Посереднє програмне забезпечення може бути змонтоване і з усіма (). Єдина відмінність полягає в тому, що шлях монтажу позбавлений під час виконання програмного забезпечення.
Хатіян

4

Так, app.all()отримує виклик, коли конкретний URI запитується будь-яким типом запиту (POST, GET, PUT або DELETE)

З іншого боку, app.use()він використовується для будь-якого проміжного програмного забезпечення, яке може бути у вас, і він встановлюється на префікс шляху, і буде називатися в будь-який час, коли буде запитано URI в рамках цього маршруту.

Ось документація для app.all & app.use .


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

1

Дві відмінності всіх вищезазначених відповідей не знаходять.

Перший: app.allприймає регулярний вираз як свій параметр шляху. app.useНЕ приймає регулярний вираз.

Другий: app.all(path,handler)або app[method](path,handler), обробник pathповинен бути однаковим до всіх path . Це, шлях [app] 'шлях завершено.

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.