【问题标题】:Remove route mappings in NodeJS Express删除 NodeJS Express 中的路由映射
【发布时间】:2023-03-26 22:15:01
【问题描述】:

我的路线映射为:

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

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

【问题讨论】:

    标签: node.js express


    【解决方案1】:

    您可以查看 Express route middleware 并可能进行重定向。

    【讨论】:

    • 现有路线一旦建立,我似乎根本无法修改。这包括添加新的中间件。虽然现在我要使用 next('route') 命令
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:
      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://...awesomefn2时会被调用:)

      编辑:修复代码

      Edit2:再次修复...

      Edit3:也许更简单的解决方案是在某个时候清除路由并重新填充它们:

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

      【讨论】:

        【解决方案4】:

        Express(至少从 3.0.5 开始)将其所有路线保留在 app.routes 中。来自documentation

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

        您的app.routes 应该与此类似:

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

        因此,您应该能够循环访问app.routes.get,直到找到您要查找的内容,然后将其删除。

        【讨论】:

        • 这非常有用。但是,当我继续尝试时,我一直遇到非常奇怪的问题。有什么办法可以写一个简单的例子吗?
        • 特别是,它也删除了我所有的静态资源映射——你知道这是为什么吗?这是我的问题,它有更多细节......stackoverflow.com/questions/15487084/…
        • 不再是,从 express@4.9.5 开始。 Checkout my answer below
        【解决方案5】:

        这会删除 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                    
        });
        

        【讨论】:

        • 在上面,route.path 包含路径名 - 如果你想通过路径删除匿名路由,你可以打开它。
        • route.path 在我的情况下未定义,但 route.route.path 具有正确的值
        【解决方案6】:

        如上所述,新的 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 中处理一些未记录的内部结构更好/更安全。

        【讨论】:

        • 我的用例是允许用户在 CMS(基于浏览器的前端应用程序)中配置路由。我还想根据 Host 字段等标头信息来确定这些路由的范围。我可能只会将所有请求路由到同一个处理程序,然后在 Express 路由 API 之外执行我自己的自定义路由。
        【解决方案7】:

        上述方法要求您为路线指定一个命名函数。我也想这样做,但没有为路由命名的函数,所以我编写了一个 npm 模块,可以通过指定路由路径来删除路由。

        给你:

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

        【讨论】:

          【解决方案8】:

          没有官方方法,但您可以使用 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。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-31
            • 2014-10-03
            • 1970-01-01
            • 1970-01-01
            • 2019-11-18
            • 2020-07-21
            相关资源
            最近更新 更多