简体   繁体   English

删除NodeJS Express中的路由映射

[英]Remove route mappings in NodeJS Express

I have a route mapped as: 我的路线映射为:

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

How can I remove / remap this route to an empty handler at runtime? 如何在运行时删除/重新映射此路由到空处理程序?

This removes app.use middlewares and/or app.VERB (get/post) routes. 这将删除app.use中间件和/或app.VERB (get / post)路由。 Tested on express@4.9.5 在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);
}

Note that it requires that the middleware/route functions have names : 请注意,它要求中间件/路由功能具有名称

app.use(function yourMiddlewareFunctionName(req, res, next) {
    ...          ^ named function
});

It won't work if the function is anonymous: 如果函数是匿名的, 它将无法工作

app.get('/path', function(req, res, next) {
    ...          ^ anonymous function, won't work                    
});

Express (at least as of 3.0.5) keeps all of its routes in app.routes . Express(至少从3.0.5开始)将所有路由保存在app.routes From the documentation : 文档

The app.routes object houses all of the routes defined mapped by the associated HTTP verb. app.routes对象包含由关联的HTTP谓词映射的所有路由。 This object may be used for introspection capabilities, for example Express uses this internally not only for routing but to provide default OPTIONS behaviour unless app.options() is used. 此对象可用于内省功能,例如,Express在内部使用此功能不仅用于路由,还提供默认的OPTIONS行为,除非使用app.options()。 Your application or framework may also remove routes by simply by removing them from this object. 您的应用程序或框架也可以通过从这个对象中删除它们来删除路由。

Your app.routes should look similar to this: 你的app.routes看起来应该类似于:

{ get: 
   [ { path: '/health/*',
       method: 'get',
       callbacks: [Object],
       keys: []}]
}

So, you should be able to loop through app.routes.get until you find what you are looking for, and then delete it. 因此,您应该能够遍历app.routes.get直到找到您要查找的内容,然后将其删除。

It is possible to remove mounted handlers (added with app.use) while the server is running, although there is no API to do this, so it isn't recommended. 在服务器运行时可以删除已安装的处理程序(添加了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;
}

This is something I need, so it's a shame there isn't a proper api, but express is just mimicing what connect does here. 这是我需要的东西,所以很遗憾没有合适的api,但express只是模仿connect在这里做什么。

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);

And then when you go to http://...awesome fn2 will be called :) 然后当你去http://...awesome fn2将被调用:)

Edit: fixed the code 编辑:修复代码

Edit2: fixed again... Edit2:再次修复......

Edit3: Maybe simpler solution is to purge routes at some point and repopulate them: 编辑3:也许更简单的解决方案是在某个时刻清除路线并重新填充它们:

// remove routes
delete app._router.map.get;
app._router.map.get = [];

// repopulate
app.get(/path/, function(req,res)
{
    ...
});

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. 我也想这样做,但没有路由的命名函数,所以我编写了一个npm模块,可以通过指定路由路径来删除路由。

Here you go: 干得好:

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

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

As already mentioned above, the new Express API doesn't seem to support this. 如上所述,新的Express API似乎不支持这一点。

  1. Is it really necessary to completely remove the mapping? 是否真的有必要彻底删除映射? If all you need is to stop serving a route, you can easily just start returning some error from the handler. 如果您只需停止提供路由,则可以轻松地从处理程序返回一些错误。

    The only (very odd) case where this wouldn't be good enough is if dynamic routes were added all the time, and you wanted to completely get rid of old ones to avoid accumulating too many... 唯一(非常奇怪)这种情况不够好的情况是,如果一直添加动态路线,并且你想彻底摆脱旧的路线,以避免积累太多......

  2. If you want to remap it (either to do something else, or to map it to something that always returns an error), you can always add another level of indirection: 如果要重新映射它(要么执行其他操作,要么将其映射到始终返回错误的内容),您始终可以添加另一级别的间接:

     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 }; 

    In my opinion this is nicer/safer than manipulating some undocumented internals in Express. 在我看来,这比在Express中操纵一些未记录的内部更好/更安全。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM