У меня есть маршрут, отображаемый как:
app.get('/health/*', function(req, res){
res.send('1');
});
Как удалить/переназначить этот маршрут на пустой обработчик во время выполнения?
У меня есть маршрут, отображаемый как:
app.get('/health/*', function(req, res){
res.send('1');
});
Как удалить/переназначить этот маршрут на пустой обработчик во время выполнения?
Это удаляет маршруты app.use
middlewares и/или app.VERB
(get/post). Протестировано по адресу [email protected]
var routes = app._router.stack;
routes.forEach(removeMiddlewares);
function removeMiddlewares(route, i, routes) {
switch (route.handle.name) {
case 'yourMiddlewareFunctionName':
case 'yourRouteFunctionName':
routes.splice(i, 1);
}
if (route.route)
route.route.stack.forEach(removeMiddlewares);
}
Обратите внимание, что для требуется, что функции промежуточного слоя/маршрута имеют имена:
app.use(function yourMiddlewareFunctionName(req, res, next) {
... ^ named function
});
Он не работает, если функция анонимна:
app.get('/path', function(req, res, next) {
... ^ anonymous function, won't work
});
Экспресс (по крайней мере, начиная с 3.0.5) сохраняет все свои маршруты в app.routes
. Из документа :
В объекте app.routes размещаются все маршруты, определенные с помощью соответствующего HTTP-глагола. Этот объект может использоваться для возможностей самоанализа, например Express использует это внутренне не только для маршрутизации, но и для обеспечения поведения по умолчанию OPTIONS, если не используется app.options(). Ваше приложение или инфраструктура также могут удалить маршруты, просто удалив их из этого объекта.
Ваш app.routes
должен выглядеть примерно так:
{ get:
[ { path: '/health/*',
method: 'get',
callbacks: [Object],
keys: []}]
}
Итак, вы должны пройти цикл app.routes.get
, пока не найдете то, что ищете, и затем удалите его.
app.get$ = function(route, callback){
var k, new_map;
// delete unwanted routes
for (k in app._router.map.get) {
if (app._router.map.get[k].path + "" === route + "") {
delete app._router.map.get[k];
}
}
// remove undefined elements
new_map = [];
for (k in app._router.map.get) {
if (typeof app._router.map.get[k] !== 'undefined') {
new_map.push(app._router.map.get[k]);
}
}
app._router.map.get = new_map;
// register route
app.get(route, callback);
};
app.get$(/awesome/, fn1);
app.get$(/awesome/, fn2);
И тогда, когда вы перейдете к http://...awesome
fn2
, вызывается:)
Изменить: исправлен код
Edit2: исправлено снова...
Edit3: Возможно, более простым решением является очистка маршрутов в какой-то момент и их повторное заполнение:
// remove routes
delete app._router.map.get;
app._router.map.get = [];
// repopulate
app.get(/path/, function(req,res)
{
...
});
Можно удалять установленные обработчики (добавленные с помощью app.use) во время работы сервера, хотя для этого нет API, поэтому его не рекомендуется.
/* Monkey patch express to support removal of routes */
require('express').HTTPServer.prototype.unmount = function (route) {
for (var i = 0, len = this.stack.length; i < len; ++i) {
if (this.stack[i].route == route) {
this.stack.splice(i, 1);
return true;
};
}
return false;
}
Это то, что мне нужно, поэтому стыдно, что нет подходящего api, но выражение просто мешает тому, что здесь делает связь.
Вышеупомянутый подход требует, чтобы у вас была именованная функция для маршрута. Я тоже хотел сделать это, но у меня не было названных функций для маршрутов, поэтому я написал модуль npm, который может удалить маршруты, указав путь маршрутизации.
Здесь вы идете:
Вы можете изучить маршрутное промежуточное ПО и, возможно, сделать переадресацию.
Как уже упоминалось выше, новый Express API, похоже, не поддерживает это.
Действительно ли необходимо полностью удалить отображение? Если вам нужно только прекратить показ маршрута, вы можете просто начать возвращать некоторую ошибку из обработчика.
Единственный (очень странный) случай, когда это было бы недостаточно, - если динамические маршруты были добавлены все время, и вы хотели полностью избавиться от старых, чтобы избежать накопления слишком много...
Если вы хотите переназначить его (либо сделать что-то другое, либо сопоставить его с тем, что всегда возвращает ошибку), вы всегда можете добавить еще один уровень косвенности:
var healthHandler = function(req, res, next) {
// do something
};
app.get('/health/*', function(req, res, next) {
healthHandler(req, res, next);
});
// later somewhere:
healthHandler = function(req, res, next) {
// do something else
};
По-моему, это лучше/безопаснее, чем манипулировать некоторыми недокументированными внутренностями в Express.