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

如何让NestJS+Fastify接受无Body的application/json请求

NestJS + Fastify 处理空JSON请求体问题

问题场景

发送带Content-Type: application/json但无请求体的POST请求时,服务返回错误:

Body cannot be empty when content-type is set to 'application/json'

初始启动代码:

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

;(async () => {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  )

  await app.listen('127.0.0.1', 3000)
})()

错误尝试:重复添加JSON解析器

尝试自定义内容类型解析器时,触发报错Content type parser 'application/json' already present,相关代码及错误信息如下:

修改后的代码:

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

;(async () => {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  )

  app.getHttpAdapter().getInstance().addContentTypeParser(
    'application/json',
    { bodyLimit: 0 },
    (_request, _payload, done) => {
      done(null, null);
    },
  );

  await app.listen('127.0.0.1', 3000)
})()

错误日志:

/data/node_modules/.pnpm/fastify@5.4.0/node_modules/fastify/lib/contentTypeParser.js:57
    throw new FST_ERR_CTP_ALREADY_PRESENT(contentType)
          ^
FastifyError [Error]: Content type parser 'application/json' already present.
    at ContentTypeParser.add (/data/node_modules/.pnpm/fastify@5.4.0/node_modules/fastify/lib/contentTypeParser.js:57:11)
    at Object.addContentTypeParser (/data/node_modules/.pnpm/fastify@5.4.0/node_modules/fastify/lib/contentTypeParser.js:357:30)

Node.js v22.19.0

使用的包版本:

{
  "@nestjs/common": "^11.0.1",
  "@nestjs/core": "^11.0.1",
  "@nestjs/platform-fastify": "^11.1.6"
}

解决方案

Fastify默认JSON解析器严格校验请求体,不允许空body。可以通过以下两种方式解决:

方案1:初始化时自定义Fastify实例(推荐)

在创建FastifyAdapter前,先配置自定义Fastify实例,替换默认的JSON解析器:

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

;(async () => {
  // 创建Fastify实例并配置
  const fastifyInstance = fastify({
    ignoreTrailingSlash: true
  })

  // 替换默认的application/json解析器
  fastifyInstance.addContentTypeParser(
    'application/json',
    { parseAs: 'buffer' },
    (req, body, done) => {
      // 处理空请求体
      if (body.length === 0) {
        return done(null, null)
      }
      // 正常解析JSON
      try {
        const json = JSON.parse(body.toString())
        done(null, json)
      } catch (err) {
        err.statusCode = 400
        done(err, undefined)
      }
    }
  )

  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(fastifyInstance),
  )

  await app.listen('127.0.0.1', 3000)
})()

方案2:创建Nest应用后替换解析器

先检查并移除已存在的JSON解析器,再添加自定义逻辑:

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

;(async () => {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  )

  const fastifyInstance = app.getHttpAdapter().getInstance()
  
  // 移除已存在的解析器
  if (fastifyInstance.hasContentTypeParser('application/json')) {
    fastifyInstance.removeContentTypeParser('application/json')
  }

  // 添加自定义解析器
  fastifyInstance.addContentTypeParser(
    'application/json',
    { parseAs: 'buffer' },
    (req, body, done) => {
      if (body.length === 0) {
        return done(null, null)
      }
      try {
        const json = JSON.parse(body.toString())
        done(null, json)
      } catch (err) {
        err.statusCode = 400
        done(err, undefined)
      }
    }
  )

  await app.listen('127.0.0.1', 3000)
})()

原理说明

Fastify默认的JSON解析器会强制校验请求体存在性,当Content-Type标记为JSON但无内容时触发错误。通过替换解析器,我们可以手动处理空body场景,返回null或空对象,跳过校验报错逻辑。

内容的提问来源于stack exchange,提问作者puz_zle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 06:24:53