NestJS如何获取包含文件的DTO数组?
在NestJS中处理包含文件的DTO数组
因为文件无法通过纯JSON格式传输,必须使用multipart/form-data类型的请求,以下是具体实现步骤:
1. 修正DTO定义
添加class-validator装饰器做参数校验,确保字段类型合法:
import { IsString } from 'class-validator'; import { File } from 'express'; export class FileDto { @IsString() brand: string; file: File; }
2. 实现控制器逻辑
使用AnyFilesInterceptor处理多文件上传,手动将请求体中的brand字段与上传的文件映射为DTO数组:
import { Controller, Post, UseInterceptors, UploadedFiles, Body, BadRequestException } from '@nestjs/common'; import { AnyFilesInterceptor } from '@nestjs/platform-express'; import { validate } from 'class-validator'; import { plainToInstance } from 'class-transformer'; import { FileDto } from './dto/file.dto'; @Controller('upload') export class UploadController { @Post('batch') @UseInterceptors(AnyFilesInterceptor()) async uploadBatch( @Body() body: { items: { brand: string }[] }, @UploadedFiles() files: Express.Multer.File[], ) { // 校验brand数组长度与文件数量是否匹配 if (body.items.length !== files.length) { throw new BadRequestException('Brand数量与文件数量不匹配'); } // 映射并验证DTO数组 const dtoArray = plainToInstance(FileDto, body.items.map((item, index) => ({ brand: item.brand, file: files[index], }))); for (const dto of dtoArray) { const errors = await validate(dto); if (errors.length > 0) { throw new BadRequestException('参数校验失败'); } } // 后续业务逻辑,比如保存文件、入库等 return dtoArray; } }
3. 前端请求示例
使用FormData构造请求,按数组索引对应brand和file字段:
const formData = new FormData(); // 第一个上传项 formData.append('items[0][brand]', 'A'); formData.append('items[0][file]', document.querySelector('#file1').files[0]); // 第二个上传项 formData.append('items[1][brand]', 'B'); formData.append('items[1][file]', document.querySelector('#file2').files[0]); // 发送POST请求 fetch('/upload/batch', { method: 'POST', body: formData, });
关键说明
- 必须使用
multipart/form-data请求类型,不能用普通JSON传输文件 - 前端需要严格按照
items[index][brand]和items[index][file]的格式添加字段,确保后端能正确解析请求体 - 后端需校验
brand数组长度与文件数量一致,避免映射错误
内容的提问来源于stack exchange,提问作者minsu
相关产品推荐
相关产品推荐

