NestJS ParseFilePipe的FileTypeValidator验证正确文件仍报错
问题:多文件上传时ParseFilePipe的FileTypeValidator始终报错
通过Postman以form-data格式上传两个字段为cedula和proceedings的文件,无论上传何种类型的文件,都会触发ParseFilePipe的FileTypeValidator验证错误。相关实现代码如下:
@Public() @Post() @ApiOperation({ summary: 'Create driver' }) @UseInterceptors(FileFieldsInterceptor([ { name: 'cedula', maxCount: 1 }, { name: 'proceedings', maxCount: 1 }, ])) create( @Body() createDriverDto: CreateDriverDto, @UploadedFiles(new ParseFilePipe({ validators: [new FileTypeValidator({fileType: 'jpg'})]})) files: { cedula?: Express.Multer.File[], proceedings?: Express.Multer.File[] }) { console.log(files.cedula); return this.driverService.create(createDriverDto, files); }
原因分析
ParseFilePipe默认是针对单个文件的验证器,而@UploadedFiles接收的是包含多个文件数组的对象,直接使用FileTypeValidator会导致验证逻辑不匹配,从而触发错误。
解决方法
方法一:自定义验证器遍历验证所有文件
创建自定义验证器,遍历每个文件字段下的文件数组,逐一检查文件类型:
import { FileValidator, ValidatorOptions } from '@nestjs/common'; export class AllFileTypeValidator extends FileValidator { constructor(private readonly fileType: string) { super({} as ValidatorOptions); } isValid(files: { [fieldname: string]: Express.Multer.File[] }): boolean { // 遍历所有文件字段 for (const field in files) { const fileArray = files[field]; if (!fileArray) continue; // 检查数组中的每个文件 for (const file of fileArray) { // 可根据mimetype或文件名后缀验证,按需调整 if (!file.mimetype.includes(this.fileType)) { return false; } } } return true; } buildErrorMessage(): string { return `所有文件必须是${this.fileType}类型`; } }
在接口中使用该自定义验证器:
@UploadedFiles(new ParseFilePipe({ validators: [new AllFileTypeValidator('jpg')] })) files: { cedula?: Express.Multer.File[], proceedings?: Express.Multer.File[] }
方法二:拆分字段,单独验证每个文件
由于配置了maxCount:1(每个字段仅允许上传一个文件),可拆分使用@UploadedFile装饰器为每个字段单独添加验证:
@Public() @Post() @ApiOperation({ summary: 'Create driver' }) @UseInterceptors(FileFieldsInterceptor([ { name: 'cedula', maxCount: 1 }, { name: 'proceedings', maxCount: 1 }, ])) create( @Body() createDriverDto: CreateDriverDto, @UploadedFile('cedula', new ParseFilePipe({ validators: [new FileTypeValidator({ fileType: 'jpg' })] })) cedula: Express.Multer.File, @UploadedFile('proceedings', new ParseFilePipe({ validators: [new FileTypeValidator({ fileType: 'jpg' })] })) proceedings: Express.Multer.File, ) { const files = { cedula: [cedula], proceedings: [proceedings] }; console.log(files.cedula); return this.driverService.create(createDriverDto, files); }
补充说明
FileTypeValidator的fileType参数支持mimetype(如image/jpeg)或文件后缀(如jpg),需确保与上传文件的实际mimetype匹配。- 若需支持多种文件类型,可修改验证逻辑,例如调整mimetype判断条件为包含
jpg或png。
内容的提问来源于stack exchange,提问作者sandstorman
相关产品推荐
相关产品推荐

