关于Koa中调用中间件时访问Koa-router上下文及传递请求参数至中间件的问题咨询
问题2:如何正确地在中间件中获取请求参数?
你的逻辑错误点非常清晰:路由注册是在应用启动阶段执行的,这时候还没有任何HTTP请求进来,Koa还未创建对应的ctx对象。你在注册路由时就试图通过ctx.request.query.projectid获取参数,这时候ctx根本不存在,自然会得到undefined或者报错。
你的中间件定义是正确的(高阶函数的写法没问题),但调用方式错了。正确的做法是:把获取动态请求参数的逻辑放到中间件的内层函数中——也就是那个接收ctx和next的异步函数里,因为这个函数是每次请求到来时才会执行的,这时候ctx已经被创建,包含了当前请求的所有信息。
给你调整后的代码示例:
中间件定义(保留你的高阶函数结构,支持传入静态配置)
module.exports.myMiddleware = (staticConfig) => async (ctx, next) => { // 这里是请求处理阶段,ctx已经存在,可以获取请求参数 const projectid = ctx.request.query.projectid; // 接下来用projectid做你需要的逻辑,比如验证、业务处理等 if (!projectid) { ctx.status = 400; ctx.body = 'projectid 参数必填'; return; } // 如果需要,可以把projectid挂载到ctx上,方便后续路由处理函数使用 ctx.state.projectid = projectid; // 继续执行下一个中间件或路由处理函数 await next(); };
路由注册(只传入静态配置,动态参数在中间件内部获取)
// 这里不需要在注册时传动态的projectid,因为还没有请求 router.get('/:id', myMiddleware({ someStaticSetting: 'foo' }), async (ctx) => { // 这里可以直接使用中间件挂载到ctx.state上的projectid ctx.body = { id: ctx.params.id, projectid: ctx.state.projectid }; });
简单总结下:
- 应用启动阶段:注册路由、定义中间件外壳,此时没有请求,无法获取
ctx相关的动态参数 - 请求处理阶段:中间件的内层函数执行,此时
ctx已创建,可以安全地获取请求参数、处理业务逻辑
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

