在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来删除路由。
干得好:
您可以查看Express 路由中间件,并可能执行redirect。
如上所述,新的Express API似乎不支持这一点。
-
是否真的有必要彻底删除映射? 如果你只需要停止服务路线,你可以很容易地从处理程序开始返回一些错误。
唯一的(非常奇怪的)这种情况不够好的情况是,如果dynamic路由被一直添加,并且你想彻底摆脱旧的情况,以避免累积太多…
-
如果你想重新映射它(要么做别的事情,要么映射它总是返回一个错误),你总是可以添加另一个间接层次:
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中操作一些无证内部的内容更安全。