删除NodeJS Express中的路由Map

dzhpxtsq  于 11个月前  发布在  Node.js
关注(0)|答案(9)|浏览(179)

我有一个Map的路线:

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

字符串
如何在运行时将此路由删除/重新Map到空处理程序?

kcugc4gi

kcugc4gi1#

这将删除app.use中间件和/或app.VERB(get/post)路由。在email protected(https://stackoverflow.com/cdn-cgi/l/email-protection)上测试

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

56lgkhnf

56lgkhnf2#

Express(至少从3.0.5开始)将其所有路由保存在app.routes中。从文档中可以看到:
app.routes对象包含所有由相关HTTP动词Map的路由。此对象可用于自省功能,例如Express在内部使用此对象不仅用于路由,还用于提供默认OPTIONS行为,除非使用app.options()。您的应用程序或框架也可以通过简单地从此对象中删除路由来删除路由。
你的app.routes应该看起来像这样:

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

字符串
因此,您应该能够循环遍历app.routes.get,直到找到要查找的内容,然后删除它。

tjvv9vkg

tjvv9vkg3#

上面的方法需要你有一个命名的函数来处理路由。我也想这样做,但是没有命名的函数来处理路由,所以我写了一个npm模块,可以通过指定路由路径来删除路由。
给您:
https://www.npmjs.com/package/express-remove-route

7vhp5slm

7vhp5slm4#

可以在服务器运行时删除挂载的处理程序(通过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在这里所做的事情。

slhcrj9b

slhcrj9b5#

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将被调用:)
编辑:修复了代码
编辑2:再次修复…
编辑3:也许更简单的解决方案是在某个时候清除路由并重新填充它们:

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

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

3npbholx

3npbholx6#

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

pgccezyw

pgccezyw7#

正如上面已经提到的,新的Express API似乎不支持这一点。
1.真的有必要完全删除Map吗?如果你需要的只是停止服务一个路由,你可以很容易地从处理程序返回一些错误。
唯一(非常奇怪)的情况是,如果动态路由一直被添加,并且您希望完全摆脱旧路由以避免积累太多的路由,那么这就不够好了。
1.如果你想重新Map它(或者做其他事情,或者将它Map到总是返回错误的东西),你总是可以添加另一个间接层:

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

wgx48brx

wgx48brx8#

没有正式的方法,但你可以用stack来实现。

function DeleteUserRouter(appName){

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

字符串
appName是路径名。
过滤router为express.Router的router.route.stack中的方法,或者您可以对应用程序执行相同的操作,但使用app._router. stack。

注意:4.0以下版本使用-app. router. stack。

oogrdqng

oogrdqng9#

如果您想删除所有路由,您可以通过app._routes.stack1)或express.Router().stack2)向后搜索并删除每个路由:

1.使用Express应用程序

let i = app._router.stack.length
while(i--) {
    app._router.stack.splice(i, 1)
}

字符串

2.使用express.Router()

let i = router.stack.length
while(i--) {
    router.stack.splice(i, 1)
}

工作示例

npm install express
然后

1.使用Express应用程序

const express = require("express")

let app = express()

// Respond on first attempt, then remove all routes
app.get('/health/*', function(req, res){
    res.send('1')
    removeRoutes()
})

function removeRoutes() {
    let i = app._router.stack.length
    while(i--) {
        app._router.stack.splice(i, 1)
    }
}

app.listen(3000, () => console.log('Example app is listening on port 3000.'))

2.使用express.Router()

const express = require("express")

let app = express()

let router = express.Router()

// Respond on first attempt, then remove all routes
router.get('/health/*', function(req, res){
    res.send('1')
    removeRoutes()
})

function removeRoutes() {
    let i = router.stack.length
    while(i--) {
        router.stack.splice(i, 1)
    }
}

app.use('/', router)
app.listen(3000, () => console.log('Example app is listening on port 3000.'))

相关问题