Есть ли полезная разница между app.all('*', ... )
и app.use('/', ...)
в Node.JS Express?
Есть ли полезная разница между app.all('*', ... )
и app.use('/', ...)
в Node.JS Express?
Ответы:
В большинстве случаев они будут работать одинаково. Самая большая разница - это порядок, в котором будет применяться промежуточное ПО:
app.all()
подключается к маршрутизатору приложения, поэтому он используется всякий раз, когда достигается промежуточное ПО app.router (которое обрабатывает все маршруты методов ... GET, POST и т. д.).ВНИМАНИЕ: app.router устарел в express 4.x
app.use()
подключается к основному стеку промежуточного программного обеспечения приложения, поэтому он используется в порядке, указанном промежуточным программным обеспечением. например, если вы поместите его первым, он будет запущен первым. Если поставить его в последнюю очередь (после маршрутизатора), обычно он вообще не запускается.Обычно, если вы хотите сделать что-то глобально для всех маршрутов, app.use () - лучший вариант. Кроме того, у него меньше шансов на будущие ошибки, так как Express 0.4, вероятно, отбросит неявный маршрутизатор (это означает, что положение маршрутизатора в промежуточном программном обеспечении будет более важным, чем сейчас, поскольку вам технически даже не нужно его использовать. сейчас).
next("route")
с app.all
, но не с app.use
.
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
app.use:
app.all:
Взгляните на этот пример кода 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
С app.use()
, путь "монтирования" удаляется и не отображается для функции промежуточного слоя:
app.use('/static', express.static(__dirname + '/public'));
Смонтированные функции промежуточного программного обеспечения ( express.static
) не вызываются, если они не req.url
содержат этот префикс ( /static
), после чего он удаляется при вызове функции.
Причём app.all()
, нет такого поведения.
Да, app.all()
вызывается, когда конкретный URI запрашивается с помощью любого типа метода запроса (POST, GET, PUT или DELETE)
С другой стороны app.use()
, используется для любого промежуточного программного обеспечения, которое у вас может быть, и оно монтируется на префикс пути и будет вызываться каждый раз, когда запрашивается URI для этого маршрута.
Два различия во всех приведенных выше ответах не упоминаются.
Первый: 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');
});
Есть два основных отличия:
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();});