同一POST路由不同查询参数,如何配置专属中间件?
解决方案
方法1:让每个处理模块定义专属中间件集合
修改处理模块的导出结构,让它包含专属中间件数组和核心处理函数,这样就能在主路由里动态加载并应用对应中间件:
示例:./funcs/onlineFriends.js
// 定义该路由专属的中间件 const authMiddleware = (req, res, next) => { // 示例中间件逻辑:验证请求头 if (!req.headers.authorization) { return res.sendStatus(401); } next(); // 调用next进入后续处理 }; module.exports = { middlewares: [authMiddleware], // 可添加多个中间件 handler: (req, res, next) => { return res.sendStatus(200); } };
修改server.js的路由逻辑
app.post("/friends", (req, res, next) => { const d = req.query.d; if (!d) { return res.sendStatus(400); // 处理参数缺失的情况 } try { const { middlewares = [], handler } = require(`./funcs/${d}.js`); // 依次执行中间件,完成后调用核心处理函数 const runMiddlewares = (index) => { if (index === middlewares.length) { return handler(req, res, next); } middlewares[index](req, res, () => runMiddlewares(index + 1)); }; runMiddlewares(0); } catch (err) { // 处理模块不存在的异常 return res.sendStatus(404); } });
方法2:在处理函数内正确处理中间件异步流程
如果不想修改模块结构,可在处理函数内确保中间件执行完成后再发送响应,核心是避免在中间件未完成时触发响应:
示例:./funcs/onlineFriends.js
const middleware = (req, res, next) => { // 模拟异步中间件逻辑,比如数据库查询 setTimeout(() => { req.userInfo = { id: 1001 }; next(); // 调用next标记中间件处理完成 }, 100); }; module.exports = (req, res, next) => { // 把响应逻辑放在中间件的回调里 middleware(req, res, () => { return res.sendStatus(200); }); };
错误原因说明
你之前的写法直接调用middleware(req, res, next)后立刻执行res.sendStatus(200),但中间件内部可能已经调用了res.send或next(next可能触发其他发送响应的逻辑),导致同一个请求被多次发送响应,从而触发Cannot set headers after they are sent to the client错误。必须保证一个请求只发送一次响应,且等待中间件的异步流程完成后再执行响应逻辑。
内容的提问来源于stack exchange,提问作者jeputier
相关产品推荐
相关产品推荐

