Javascript Node.js express-无需进入route功能即可获取route参数,以进行快速分析跟踪

Javascript Node.js express-无需进入route功能即可获取route参数,以进行快速分析跟踪,javascript,node.js,express,google-analytics,analytics,Javascript,Node.js,Express,Google Analytics,Analytics,我的目标是为API中的每条路线发送一个分析事件。与使用调用的整个完整路由保存事件不同,我希望将基本url保存为事件,并将路由的参数保存为事件的变量。例如,保存分析事件时 不是这个: { event_title: "API User Event" category: "domain.com/api/user_routes/route_1/value_of_param_one" } { event_title: "API User Event" category: "domain.

我的目标是为API中的每条路线发送一个分析事件。与使用调用的整个完整路由保存事件不同,我希望将基本url保存为事件,并将路由的参数保存为事件的变量。例如,保存分析事件时

不是这个:

{
  event_title: "API User Event"
  category: "domain.com/api/user_routes/route_1/value_of_param_one"
}
{
  event_title: "API User Event"
  category: "domain.com/api/user_routes/route_1"
  params: {
     param_one: "value_of_param_one"
  }
}
但是这个:

{
  event_title: "API User Event"
  category: "domain.com/api/user_routes/route_1/value_of_param_one"
}
{
  event_title: "API User Event"
  category: "domain.com/api/user_routes/route_1"
  params: {
     param_one: "value_of_param_one"
  }
}
我希望有一个全局函数,从请求变量获取参数,但是,如果您在更高的级别(而不是路由级别)执行此操作

myWrapperFunction将检测/api/user_路由之后的任何内容作为参数。从我的实验中,我只能成功地检测到特定路由函数中的实际参数。然而,这种方法要求我要么编辑每个路由函数,要么像这样包装它

router.get('/route_1/:param_one', (req, res) => Utility.analyticsEvent(userController.routeOneFunction, req, res));

router.get('/route_2/:param_one', (req, res) => Utility.analyticsEvent(userController.routeTwoFunction, req, res));

router.get('/route_3/:param_one', (req, res) => Utility.analyticsEvent(userController.routeThreeFunction, req, res));
是否有一种方法可以检测路线的实际参数而不实际进入功能本身?或者这是对express的一个限制,因为它在找到沿路径遍历的第一个匹配选项之前不知道路径的细节

编辑如果在express匹配特定路线之前无法知道参数:在执行路线功能之前,您是否可以运行一个功能,告诉您将匹配哪个路线并指定参数


欢迎大家发表意见

我认为一种方法是编写如下所示的中间件

// This will get executed before every request. As we'll add this with app.use() with top level middlewares

function customMiddleware (req, res, next) {
   let url = req.baseUrl;
   // some if else logic to re-route

   if( url.includes('/api/user_routes')) {
     let urlSplit = url.split();
     if( url[urlSplit.length() - 1] == 'param_one' ) {
       res.redirect('/api/user_routes/route_1') 
     }
     else if(url[urlSplit.length() - 1] == 'param_tow' ) {
       res.redirect('/api/user_routes/route_1') 
     }
     // and so on

   } else {
      // executes other middleware or go to matching route
      next()
   }
}

app.use(customMiddleware)
通过覆盖response.json函数,找到了在调用后执行此操作的方法

app.use(function (req, res, next) {
  var json = res.json;
  res.json = function (body) {
      // Send analytics event before returning response     
      try { 
        // Routes that don't need to be tracked with analytics
        let notIncludeRoutes = [
          "some_not_tracked_route"
        ];
        let route = req.baseUrl + req.route.path;

        if(notIncludeRoutes.indexOf(route) === -1) {
          // Track route and params
          let route_params = res.req.params;
          Utility.analyticsEvent(route, route_params);
        }
      } catch(error) {
        // Don't block call if there was an error with analytics, but do log it
        console.log("ANALYTICS ERROR: ", error);
      }

      json.call(this, body);
  };
  next();
});

“检测路线的实际参数”是什么意思?您可以使用
req.URL
req.path
,req.originalUrl
req.query`准确地查看中间件中的URL,并获取您想要的任何内容。如果您没有指定一个特定的URL模式,该模式带有与中间件匹配的参数,那么它将不会为您解析参数,但您可以自己以一种通用的方式解析它们。您可以指定所需的模式并让Express来执行,或者以更通用的方式从URL解析内容。这不是Express的“限制”。这就是任何这样的系统的工作原理。@jfriend00谢谢您的回复。指定模式不是我们的选择。我们有大约100个不同的路径。在每个路由中(在您现有的处理程序中或在您添加到路由定义本身的中间件函数中),您可以查看
req.route()
以查看匹配的路径,在
req.params
以查看为该路由定义的参数和
req.query
。如果您有数百条不同的路径,它们大部分都在做相同的事情,那么我建议您可以将它们组合成一条执行一些常见逻辑的路径,然后根据在URL中看到的内容检查URL和分支。