如何在Express.JS中获取下一个要调用的中间件函数的名称
实现方案
你要的需求有两种可行实现方式,分别适配不同的使用场景:
方案一:手动传入目标函数名(最稳定,推荐新手使用)
不需要依赖Express内部逻辑,兼容性最强,不会因为Express版本迭代失效:
// 改造授权中间件为高阶函数,接收要校验的处理函数名作为入参 const authorizeRoute = (handlerName) => (req, res, next) => { if (isUserAuthorized(req.user.id, handlerName)) { next() } else { res.sendStatus(403) } } // 注册路由时手动传入对应处理函数的名称 app.get("/users", authorizeRoute("getUsers"), controller.getUsers) app.get("/users/:id/posts", authorizeRoute("getUserPosts"), controller.getUserPosts)
方案二:自动获取下一个处理函数名
通过Express提供的req.route内部属性自动获取,不需要手动传参,适配Express 4.x及以上版本:
const authorizeRoute = (req, res, next) => { // 监听路由匹配完成事件,此时req.route属性会被挂载 req.once('router', () => { // 从路由栈中取第一个路由处理函数的名称 // 如果你的路由有多个前置中间件,调整stack的索引即可拿到对应位置的函数名 const nextFunctionName = req.route.stack[0].handle.name // 如需controller.xxx格式,自行拼接即可: // const nextFunctionName = `controller.${req.route.stack[0].handle.name}` if (isUserAuthorized(req.user.id, nextFunctionName)) { next() } else { res.sendStatus(403) } }) } // 注意:全局注册授权中间件必须放在所有路由注册之前 app.use(authorizeRoute) app.get("/users", controller.getUsers) app.get("/users/:id/posts", controller.getUserPosts)
注意事项
- 自动获取的方式要求你的路由处理函数必须是具名函数,如果是匿名函数,
handle.name会返回空字符串,无法正常获取名称 - 如果单个路由注册了多个处理函数(比如参数校验、分页处理等中间件),调整
req.route.stack的索引即可拿到对应位置的函数名
内容的提问来源于stack exchange,提问作者Jose V Sebastian
相关产品推荐
相关产品推荐

