Fastify onRequest钩子捕获原始请求体后路由处理器未触发
问题解决:Fastify onRequest钩子捕获原始请求体后路由失效
问题原因
你在onRequest钩子中直接监听request.raw的data和end事件,会提前消费请求体的数据流。Fastify内部的请求体解析器依赖这个数据流解析请求内容,一旦数据流被耗尽,解析器无法获取数据,就会导致路由处理器无法正常触发。
解决方案
方案1:手动重新注入数据流
捕获完原始请求体后,需要把数据流重新注入request.raw,让Fastify的解析器能继续处理。用Node.js的stream.PassThrough实现:
const { PassThrough } = require('stream'); fastify.addHook('onRequest', (request, reply, done) => { console.log('onRequest hook is running'); const rawDataChunks = []; request.raw.on('data', (chunk) => { console.log(chunk); rawDataChunks.push(chunk); }); request.raw.on('end', () => { const rawData = Buffer.concat(rawDataChunks).toString(); console.log('RAW DATA:', rawData); request.rawData = rawData; // 创建新的流并重新注入数据 const passThrough = new PassThrough(); passThrough.end(Buffer.concat(rawDataChunks)); request.raw = passThrough; done(); }); }); fastify.post('/', (request, reply) => { console.log('Route handler is running'); reply.send({ status: 'ok' }); });
方案2:使用官方raw-body插件(推荐)
Fastify官方提供了专门的@fastify/raw-body插件,无需手动处理流,就能安全获取原始请求体:
- 安装插件:
npm install @fastify/raw-body
- 配置使用:
const fastify = require('fastify')(); fastify.register(require('@fastify/raw-body'), { field: 'rawBody', // 原始请求体挂载到request.rawBody global: false, // 仅对指定路由生效 encoding: 'utf8', // 编码格式,设为null可获取Buffer }); // 目标路由启用rawBody配置 fastify.post('/', { config: { rawBody: true } }, (request, reply) => { console.log('Route handler is running'); console.log('RAW DATA:', request.rawBody); reply.send({ status: 'ok' }); }); fastify.listen({ port: 3000 }, (err) => { if (err) throw err; console.log('Server running on port 3000'); });
验证说明
两种方案都能正常捕获原始请求体,同时保证路由处理器正常执行。方案2是官方推荐方式,更稳定且无需手动处理流的细节问题。
内容的提问来源于stack exchange,提问作者aporro
相关产品推荐
相关产品推荐

