24

我有一条路线映射为:

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

如何在运行时将此路由删除/重新映射到空处理程序?

4

8 回答 8

35

这将删除app.use中间件和/或app.VERB(get/post) 路由。在 express@4.9.5 上测试

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                    
});
于 2015-02-06T15:49:42.137 回答
25

Express(至少从 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直到找到您要查找的内容,然后将其删除。

于 2012-12-25T22:12:22.200 回答
8

The above approach requires you have a named function for the route. I wanted to do this as well but didn't have named functions for routes so I wrote an npm module that can remove routes by specifying the routing path.

Here you go:

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

于 2015-11-08T00:36:26.770 回答
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,但 express 只是在模仿 connect 在这里所做的事情。

于 2012-06-07T22:18:39.543 回答
4
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)
{
    ...
});
于 2012-10-14T18:28:29.870 回答
3

您可以查看 Express路由中间件并可能进行重定向。

于 2012-04-30T05:14:04.413 回答
3

如上所述,新的 Express API 似乎不支持这一点。

  1. 真的有必要完全删除映射吗?如果您只需要停止为路由提供服务,则可以轻松地开始从处理程序返回一些错误。

    唯一(非常奇怪)这还不够好的情况是,如果一直添加动态路由,并且您想完全摆脱旧路由以避免积累太多...

  2. 如果你想重新映射它(要么做其他事情,要么将它映射到总是返回错误的东西),你总是可以添加另一个级别的间接:

    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 中操作一些未记录的内部结构更好/更安全。

于 2015-08-15T22:52:02.580 回答
0

There is no official method but you can do this with stack.

function DeleteUserRouter(appName){

router.stack = router.stack.filter((route)=>{
  if(route.route.path == `/${appName}`){
     return false;
  }
  return true;
});
}

appName is path name .

Filter the methods in the router.route.stack where the router is express.Router or you can do the same for the app but with app._router.stack.

Note: For below 4.0 use - app.router.stack.

于 2021-09-03T14:11:06.500 回答