如何获取Fastify请求的原始请求体?(原Express用户首次使用)
嘿,从Express转Fastify遇到这个问题太正常了!我当初刚用Fastify做Webhook验证的时候也卡在这里,毕竟两者处理请求体的逻辑不太一样。下面给你两种实用的方法,都能拿到未经任何中间件修改的原始请求体,完美适配签名验证的需求:
方法一:开启Fastify的raw配置(最省心,和Express用法接近)
Fastify其实内置了获取原始请求体的能力,只需要在创建实例或者路由级别开启raw选项就行,开启后直接通过request.rawBody就能拿到,和Express里的用法几乎一模一样!
全局开启(所有路由都能拿到rawBody)
const fastify = require('fastify')({ bodyParser: { raw: { enabled: true, // 可选:指定只针对特定Content-Type生效,比如Webhook常用的application/json // contentType: 'application/json' } } }); fastify.post('/webhook', (request, reply) => { // 直接拿到原始请求体 const rawBody = request.rawBody; // 这里就可以用rawBody和请求头里的签名做验证了 // ...你的签名校验逻辑 reply.send({ status: 'success' }); });
路由级别单独开启(更灵活,只给需要的路由开)
如果只有个别路由需要原始请求体,没必要全局配置,直接在路由里单独设置就行:
fastify.post('/webhook', { bodyParser: { raw: { enabled: true } } }, (request, reply) => { const rawBody = request.rawBody; // ...处理验证逻辑 reply.send({ status: 'success' }); });
方法二:直接操作Node.js原生请求对象(更底层)
如果上面的方法不符合你的场景,还可以直接用Node.js原生的request.raw对象(它是IncomingMessage实例)手动收集请求体。不过要记得先禁用Fastify自带的bodyParser,不然它会提前解析请求体,你就拿不到原始内容了。
示例代码:
fastify.post('/webhook', { // 必须禁用自带的bodyParser,避免提前解析请求体 bodyParser: false }, (request, reply) => { let rawBody = ''; // 监听data事件收集数据块 request.raw.on('data', (chunk) => { rawBody += chunk.toString('utf8'); // 这里可以指定编码,默认utf8就行 }); // 监听end事件,请求体接收完成后处理 request.raw.on('end', () => { // 现在rawBody就是完整的原始请求体了 // ...你的签名验证逻辑 reply.send({ status: 'success' }); }); });
小提示
做Webhook签名验证的时候,一定要确保原始请求体的编码和发送方一致(一般都是utf-8),上面两种方法默认都是用utf-8解析的,要是遇到特殊编码可以手动调整。
内容的提问来源于stack exchange,提问作者mikemaccana
相关产品推荐
相关产品推荐

