如何让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
相关产品推荐
相关产品推荐

