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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 10:53:12