Skip to content

原始请求体

能够访问原始请求体(raw body)的一个最常见场景,是做 webhook 签名校验。通常在计算 HMAC 哈希时,你需要的是“尚未被反序列化”的原始请求体。

警告

该特性仅在启用了内置全局 body parser 中间件时可用。也就是说,创建应用时不能传入 bodyParser: false

与 Express 配合使用

首先,在创建 Nest Express 应用时启用该选项:

typescript
import { NestFactory } from '@nestjs/core';
import type { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';

// 在 "bootstrap" 函数中
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
  rawBody: true,
});
await app.listen(process.env.PORT ?? 3000);

如果想在控制器中访问原始请求体,Nest 提供了一个便捷接口 RawBodyRequest,它会在请求对象上暴露 rawBody 字段。你只需将请求类型声明为 RawBodyRequest 即可:

typescript
import { Controller, Post, RawBodyRequest, Req } from '@nestjs/common';
import { Request } from 'express';

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<Request>) {
    const raw = req.rawBody; // 返回一个 `Buffer`
  }
}

注册不同的解析器

默认情况下,只会注册 jsonurlencoded 解析器。如果你想动态注册其他解析器,需要显式调用相关方法。

例如,要注册一个 text 解析器,可以这样写:

typescript
app.useBodyParser('text');

警告

请确保传给 NestFactory.create() 的应用类型是正确的。对于 Express 应用,正确类型应为 NestExpressApplication。否则将找不到 .useBodyParser() 方法。

Body parser 大小限制

如果你的应用需要解析一个比 Express 默认 100kb 更大的请求体,可以这样设置:

typescript
app.useBodyParser('json', { limit: '10mb' });

.useBodyParser() 方法会自动遵守应用创建时传入的 rawBody 配置。

与 Fastify 配合使用

首先,在创建 Nest Fastify 应用时启用该选项:

typescript
import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

// 在 "bootstrap" 函数中
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
  {
    rawBody: true,
  },
);
await app.listen(process.env.PORT ?? 3000);

如果想在控制器中访问原始请求体,同样可以使用 RawBodyRequest 接口:

typescript
import { Controller, Post, RawBodyRequest, Req } from '@nestjs/common';
import { FastifyRequest } from 'fastify';

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<FastifyRequest>) {
    const raw = req.rawBody; // 返回一个 `Buffer`
  }
}

注册不同的解析器

默认情况下,只会注册 application/jsonapplication/x-www-form-urlencoded 两种解析器。如果你想动态注册其他解析器,也需要显式处理。

例如,要注册一个 text/plain 解析器,可以这样写:

typescript
app.useBodyParser('text/plain');

警告

请确保传给 NestFactory.create() 的应用类型是正确的。对于 Fastify 应用,正确类型应为 NestFastifyApplication。否则将找不到 .useBodyParser() 方法。

Body parser 大小限制

如果你的应用需要解析一个比 Fastify 默认 1MiB 更大的请求体,可以这样设置:

typescript
const bodyLimit = 10_485_760; // 10MiB
app.useBodyParser('application/json', { bodyLimit });

.useBodyParser() 方法同样会自动遵守应用创建时传入的 rawBody 配置。

基于 NestJS 官方文档翻译