NestJS+Fastify接收Multipart文件报错:Unsupported Media Type
解决NestJS+Fastify文件上传的Unsupported Media Type问题
核心问题根源
你用的FileInterceptor是适配Express的,而Fastify有独立的文件处理机制,直接混用会导致Multipart类型不被识别;同时Swagger未配置对应表单类型,所以看不到文件上传选项。
分步解决
1. 安装Fastify文件处理依赖
先安装fastify-multipart,这是Fastify处理Multipart请求的核心插件:
npm install fastify-multipart # 或用yarn yarn add fastify-multipart
2. 在应用启动时注册插件
打开main.ts,创建Fastify应用后注册multipart插件:
import { NestFactory } from '@nestjs/core'; import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create<NestFastifyApplication>( AppModule, new FastifyAdapter() ); // 注册fastify-multipart插件 await app.register(require('fastify-multipart')); // 其他配置如CORS await app.listen(5050); } bootstrap();
3. 替换控制器里的文件拦截器
把Express的FileInterceptor换成Fastify专属的FastifyFileInterceptor,同时调整文件类型:
// log-handler.controller.ts import { Controller, Post, Body, UseInterceptors } from '@nestjs/common'; // 导入Fastify的文件拦截器与类型 import { FastifyFileInterceptor, UploadedFile } from '@nestjs/platform-fastify'; import { QueryBus } from '@nestjs/cqrs'; import { PostLogQuery } from './your-query-path'; // 导入Swagger装饰器配置表单类型 import { ApiConsumes, ApiBody, ApiOperation } from '@nestjs/swagger'; @Controller('log-handler') export class LogHandlerController{ constructor(private queryBus: QueryBus){} @Post('/api/v1/logs') // 告知Swagger这是multipart/form-data请求 @ApiConsumes('multipart/form-data') @ApiOperation({ summary: '上传日志文件' }) // 配置Swagger请求体,包含文件和DTO字段 @ApiBody({ schema: { type: 'object', properties: { // 这里填写你的DTO字段,比如appId、version等 appId: { type: 'string' }, version: { type: 'string' }, file: { type: 'string', format: 'binary', }, }, }, }) // 使用Fastify的文件拦截器,指定文件字段名为'file' @UseInterceptors(FastifyFileInterceptor('file')) async sendAppLog( @Body() query: PostLogQuery, @UploadedFile() file: any // 也可导入FastifyMultipartFile类型 ){ console.log(query); console.log(file); // 现在能正常获取文件信息 return this.queryBus.execute(query); } }
4. 前端Angular请求调整
必须用FormData构造请求体,不能直接传JSON:
// Angular组件/service代码 uploadLogFile(file: File, logData: PostLogQuery) { const formData = new FormData(); // 追加DTO的各个字段 formData.append('appId', logData.appId); formData.append('version', logData.version); // 追加文件 formData.append('file', file); return this.http.post('/log-handler/api/v1/logs', formData); }
注意:不要手动设置
Content-Type为multipart/form-data,Angular会自动添加正确的边界标识,手动设置反而会触发错误。
5. 验证Swagger显示
重启服务后访问localhost:5050/api,/api/v1/logs接口会显示文件上传选项,同时支持填写DTO字段。
额外注意点
- 若需多文件上传或自定义存储逻辑,可参考NestJS官方文档中Fastify文件上传章节,适配你的S3上传流程。
- 确保
PostLogQuery的字段名与FormData中的键名完全一致,否则@Body()无法正确解析。
内容的提问来源于stack exchange,提问作者Dahlia_y
相关产品推荐
相关产品推荐

