在NodeJS Express中删除路由映射

我有一个路线映射为:

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

如何在运行时删除/重新映射这个路由到一个空的处理程序?

这将删除app.use中间件和/或app.VERB (get / post)路由。 经过express@4.9.5testing

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

请注意,它要求中间件/路由function具有以下名称

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

如果函数是匿名的, 它将不起作用

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

Express(至less从3.0.5开始)将其所有路由保存在app.routes 。 从文档 :

app.routes对象包含由关联的HTTP动词映射定义的所有路由。 这个对象可以用于内省function,例如Express不仅在内部使用这个路由,而且还提供默认的OPTIONS行为,除非使用app.options()。 您的应用程序或框架也可以通过从这个对象中删除路由来删除路由。

你的app.routes看起来应该类似于这个:

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

所以,你应该能够通过app.routes.get循环,直到find你正在寻找的东西,然后删除它。

 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:也许更简单的解决scheme是清除路线在某个时刻,并重新填充它们:

 // remove routes delete app._router.map.get; app._router.map.get = []; // repopulate app.get(/path/, function(req,res) { ... }); 

可以在服务器运行时删除挂载的处理程序(添加了app.use),虽然没有API来执行此操作,所以不build议这样做。

 /* 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,但expression只是模仿连接在这里。

上面的方法要求你有一个命名的function的路线。 我也想这样做,但没有命名的路由function,所以我写了一个npm模块,可以通过指定路由path来删除路由。

干得好:

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

您可以查看Express 路由中间件,并可能执行redirect。

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

  1. 是否真的有必要彻底删除映射? 如果你只需要停止服务路线,你可以很容易地从处理程序开始返回一些错误。

    唯一的(非常奇怪的)这种情况不够好的情况是,如果dynamic路由被一直添加,并且你想彻底摆脱旧的情况,以避免累积太多…

  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中操作一些无证内部的内容更安全。