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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 03:54:28