You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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插件,无需手动处理流,就能安全获取原始请求体:

  1. 安装插件:
npm install @fastify/raw-body
  1. 配置使用:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:33:22