В справочнике Express говорится, что вы можете использовать next('route')
только с обработчиками HTTP.
Вы можете предоставить несколько функций обратного вызова, которые ведут себя как промежуточное ПО для обработки запроса. Единственным исключением является то, что эти обратные вызовы могут вызывать next ('route'), чтобы обойти оставшиеся обратные вызовы маршрута. Вы можете использовать этот механизм для наложения предварительных условий на маршрут, а затем передать управление последующим маршрутам, если нет оснований продолжать работу с текущим маршрутом.
Похоже, это означает, что с next('route')
вы может выйти из цепочки массивов, пропуская оставшуюся часть массива, сразу после следующего отдельного оператора в коде, где вызывается обработчик HTTP для точно такого же пути:
const express = require('express');
let ret = "";
const app = express();
app.all("/foo", [function(req, res, next){
let x = Math.round(Math.random()) ? 'route' : null; // 50% chance for `x` being set to "route"
ret = "foo1/";
next(x); // skip the next function if `x` equals "route"
}, function(req, res, next){
ret += "foo2/";
next();
}]);
app.all("/foo", function(req, res, next){
ret += "foo3";
res.send(ret);
});
app.listen(3000);
Так что здесь запрос к localhost:3000/foo
должен заставить сервер произвольно возвращать foo1/foo2/foo3
или foo1/foo3
, что, кажется, работает.
И это вы не можете сделать с app.use
. Замена app.all
на app.use
в приведенном выше коде приводит к localhost:3000/foo
, всегда возвращающему foo1/foo2/foo3
. И. е. next(...)
никогда не вырывается из цепочки массивов, независимо от заданного аргумента.
Но это не единственное отличие, если мы говорим о реальном использовании. В другой части документации, Express API-ссылка , говорится:
Маршрут будет соответствовать любому пути, который следует по его пути немедленно, с помощью «/». Например: app.use ('/ apple', ...) будет соответствовать «/ apple», «/ apple / images», «/ apple / images / news» и т. Д.
, так как путь по умолчанию равен «/», промежуточное программное обеспечение, смонтированное без пути, будет выполняться для каждого запроса к приложению.
Мы можем использовать это следующим образом:
const express = require('express');
let ret = ""; // a string we want build and return to the client
const app = express();
app.use(function(req, res, next){ // implicitly bound to "/"
ret = "/"; // reset `ret` to "/"
next();
});
app.use("/foo", function(req, res, next){
ret += "foo/";
next();
});
app.use("/foo/bar", function(req, res, next){
ret += "bar";
res.send(ret);
});
app.use(function(req, res, next){
res.send(ret); // finally return the string
});
app.listen(3000);
Здесь вы получить:
localhost:3000/
=> /
localhost:3000/foo/
=> /foo/
localhost:3000/foo/bar
=> /foo/bar
и работает после многократного запроса.
localhost:3000/foo/asdf
запускает app.use("/", ...)
(с неявным "/"
) и app.use("/foo", ...) and the server also returns
/ foo`.
Замена app.use
на app.all
в приведенном выше коде это ломает.
Теперь, действительно ли это, наконец, только различий между промежуточным ПО уровня приложения и app.use
против Обратные вызовы обработчиков HTTP и app.all
? Или где-то еще скрывается сюрприз?