Подтвердить что ты не робот

Удаление сопоставлений маршрутов в NodeJS Express

У меня есть маршрут, отображаемый как:

app.get('/health/*', function(req, res){
    res.send('1');
});

Как удалить/переназначить этот маршрут на пустой обработчик во время выполнения?

4b9b3361

Ответ 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                    
});

Ответ 2

Экспресс (по крайней мере, начиная с 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, пока не найдете то, что ищете, и затем удалите его.

Ответ 3

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)
{
    ...
});

Ответ 4

Можно удалять установленные обработчики (добавленные с помощью 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, но выражение просто мешает тому, что здесь делает связь.

Ответ 5

Вышеупомянутый подход требует, чтобы у вас была именованная функция для маршрута. Я тоже хотел сделать это, но у меня не было названных функций для маршрутов, поэтому я написал модуль npm, который может удалить маршруты, указав путь маршрутизации.

Здесь вы идете:

https://www.npmjs.com/package/express-remove-route

Ответ 7

Как уже упоминалось выше, новый 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.