Node.js express - 无需进入路由功能即可获取路由参数以进行快速分析跟踪
Node.js express - get route params without going into the route function for quick analytics tracking
我的目标是为我的 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"
}
}
我想要一个从请求变量获取参数的全局函数,但是,如果您在更高级别(而不是路由级别)执行此操作
app.use('/api/user_routes/*', myWrapperFunction)
myWrapperFunction 将检测 /api/user_routes 之后的所有内容作为参数。根据我的实验,我只能成功检测到特定路由函数内的实际参数。但是,这种方法要求我要么编辑每个路由函数,要么像这样包装它...
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 的限制,因为它在找到第一个遍历路线的匹配选项之前不知道路线的细节?
Edit 如果无法知道 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();
});
我的目标是为我的 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"
}
}
我想要一个从请求变量获取参数的全局函数,但是,如果您在更高级别(而不是路由级别)执行此操作
app.use('/api/user_routes/*', myWrapperFunction)
myWrapperFunction 将检测 /api/user_routes 之后的所有内容作为参数。根据我的实验,我只能成功检测到特定路由函数内的实际参数。但是,这种方法要求我要么编辑每个路由函数,要么像这样包装它...
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 的限制,因为它在找到第一个遍历路线的匹配选项之前不知道路线的细节?
Edit 如果无法知道 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();
});