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

NestJS上传CSV文件时持续出现415不支持媒体类型错误求助

问题描述

我正在编写支持CSV文件上传的NestJS接口,尝试了两种实现方式:

方式一:

@Post('/bulk')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file);
}

方式二:

@Post('/bulk')
uploadFile(
  @Body(new ParseArrayPipe({ items: CreatePlaceDto })) dtos: CreatePlaceDto[], 
  @Req() request: CrudRequest) {
    console.log(dtos);
  }

但两种方式均返回415错误,错误信息如下:

{
    "statusCode": 415,
    "code": "FST_ERR_CTP_INVALID_MEDIA_TYPE",
    "error": "Unsupported Media Type",
    "message": "Unsupported Media Type: multipart/form-data; boundary=--------------------------520916914275921544205184"
}

我通过Postman测试时,已在请求头设置content-type为"multipart/form-data",并在form-data体中以"file"为键上传CSV文件。请问该问题原因是什么?恳请相关解决建议!

原因分析与解决建议

核心原因

  1. 方式二逻辑不匹配:@Body() + ParseArrayPipe是用来解析application/json类型的请求体,而文件上传依赖multipart/form-data格式,两者完全不兼容,所以方式二从根本上不适用文件上传场景。
  2. 方式一缺失必要配置:NestJS的文件上传功能依赖multer库,若未正确安装依赖或在模块中完成配置,框架无法解析multipart/form-data请求,直接抛出415错误。

解决步骤

针对方式一(正确的文件上传实现)

  1. 安装依赖包:
    执行命令安装multer及对应的类型定义:
    npm install @nestjs/platform-express multer
    npm install -D @types/multer
    
  2. 模块中配置Multer:
    在对应功能模块(比如PlaceModule)中导入MulterModule,可设置文件临时存储路径:
    import { Module } from '@nestjs/common';
    import { MulterModule } from '@nestjs/platform-express';
    import { diskStorage } from 'multer';
    import { extname } from 'path';
    import { PlaceController } from './place.controller';
    
    @Module({
      imports: [
        MulterModule.register({
          storage: diskStorage({
            destination: './uploads', // 需提前创建该目录
            filename: (req, file, cb) => {
              const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
              cb(null, file.fieldname + '-' + uniqueSuffix + extname(file.originalname));
            },
          }),
        }),
      ],
      controllers: [PlaceController],
    })
    export class PlaceModule {}
    
  3. 修正Postman请求设置:
    • 不要手动设置Content-Type为multipart/form-data,Postman会在选择form-data并添加文件后自动生成带正确boundary的请求头,手动设置反而可能导致格式不匹配。
    • 确认form-data中的键名与FileInterceptor('file')的参数一致(即file)。

额外拓展:解析CSV内容

如果需要把上传的CSV文件内容转换为CreatePlaceDto数组,可以使用csv-parser库处理:

  1. 安装依赖:
    npm install csv-parser
    
  2. 在控制器中处理文件内容:
    import * as csvParser from 'csv-parser';
    import { createReadStream } from 'fs';
    import { CreatePlaceDto } from './dto/create-place.dto';
    
    @Post('/bulk')
    @UseInterceptors(FileInterceptor('file'))
    async uploadFile(@UploadedFile() file: Express.Multer.File) {
      const results: CreatePlaceDto[] = [];
      await new Promise((resolve, reject) => {
        createReadStream(file.path)
          .pipe(csvParser())
          .on('data', (data) => results.push(data as CreatePlaceDto))
          .on('end', resolve)
          .on('error', reject);
      });
      console.log(results);
      // 后续业务逻辑处理
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:22:28