NestJS 10中如何配置文件验证器仅接受图片上传?
解决NestJS 10图片上传接口的文件类型验证失败问题
你的代码报错是因为FileTypeValidator默认验证的是文件的MIME类型(即file.mimetype字段),而非文件名后缀,但你传入的正则是匹配文件名后缀的,两者不匹配导致验证失败。比如JPG文件的MIME类型是image/jpeg,而非jpg,所以原正则无法匹配。
以下是两种正确的解决方式:
方式一:使用MIME类型匹配(推荐)
直接针对文件的MIME类型编写正则,覆盖你需要支持的图片类型:
@Post() @UseInterceptors( FileFieldsInterceptor([ { name: 'frontImg', maxCount: 1 }, { name: 'backImg', maxCount: 1 }, ]), ) async create( @Req() req: Request, @Body('title') title: string, @Body('frontImgAltText') frontImgAltText: string, @Body('category') category: Occasion, @UploadedFiles( new ParseFilePipe({ fileIsRequired: false, // 因为backImg是可选字段,允许不上传 validators: [ new FileTypeValidator({ fileType: /^image\/(jpeg|png|webp)$/ // 匹配image/jpeg、image/png、image/webp }), ], }), ) files: { frontImg: Express.Multer.File[]; backImg?: Express.Multer.File[] }, ) { // 你的业务逻辑 }
方式二:自定义验证器检查文件名后缀
如果需要严格校验文件名的后缀,可以自定义一个文件验证器:
import { FileValidator } from '@nestjs/common'; // 自定义文件后缀验证器 export class CustomFileExtensionValidator extends FileValidator { constructor(private readonly allowedExtensions: string[]) { super({}); } isValid(file?: Express.Multer.File): boolean { if (!file) return true; // 允许空文件(对应可选字段) const fileExtension = file.originalname.split('.').pop()?.toLowerCase(); return this.allowedExtensions.includes(fileExtension); } buildErrorMessage(): string { return `仅支持以下文件类型: ${this.allowedExtensions.join(', ')}`; } }
然后在接口中使用这个自定义验证器:
@UploadedFiles( new ParseFilePipe({ validators: [ new CustomFileExtensionValidator(['jpg', 'jpeg', 'png', 'webp']) ], }), ) files: { frontImg: Express.Multer.File[]; backImg?: Express.Multer.File[] },
额外注意
如果接口中有可选的文件字段(比如你的backImg),必须在ParseFilePipe中设置fileIsRequired: false,否则当不上传该文件时会触发验证失败。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

