如何在NestJS的FilesInterceptor中支持.psd/.avi/.mov文件?
问题分析与解决方案
你的问题出在FileTypeValidator的参数格式错误,以及对其验证逻辑的误解:
fileType参数格式错误:你当前使用的.(png|jpeg|jpg|pdf|gif|svg|mp4|psd|bmp|mov|avi)不是有效的正则表达式格式,FileTypeValidator只会将其当作普通字符串匹配,自然无法匹配任何真实文件的扩展名或MIME类型。- 验证逻辑依赖真实文件类型:
FileTypeValidator底层通过file-type库读取文件的magic number判断真实类型,而非仅依赖文件名后缀,这意味着即使文件名是.psd,如果文件内容不符合PSD格式,也会验证失败。
解决方案
方案1:使用正确的正则格式匹配扩展名
将fileType改为标准正则字符串(前后用/包裹),同时忽略大小写,确保能匹配所有目标扩展名:
@UseInterceptors(FilesInterceptor('upload_image', 10)) async uploadImage( @UploadedFiles( new ParseFilePipe({ validators: [ new FileTypeValidator({ // 正则匹配目标扩展名,忽略大小写 fileType: /\.(png|jpeg|jpg|pdf|gif|svg|mp4|psd|bmp|mov|avi)$/i, }), new MaxFileSizeValidator({ maxSize: 1024 * 1024 * 4 }), ], }), ) files, @Body() body: UploadFileDto, @Req() req, @Res() res, ) { // Some service logic }
方案2:基于MIME类型验证(更准确)
如果希望严格验证文件真实内容,直接使用对应格式的MIME类型正则,避免仅靠扩展名误判:
new FileTypeValidator({ fileType: /^(image\/(png|jpeg|jpg|gif|bmp|svg\+xml)|application\/pdf|video\/(mp4|quicktime|x-msvideo)|image\/vnd\.adobe\.photoshop)$/i, }),
对应MIME类型映射:
.psd:image/vnd.adobe.photoshop.avi:video/x-msvideo.mov:video/quicktime
方案3:自定义验证器(兼顾文件名后缀与真实类型)
如果需要同时检查文件名后缀和文件真实内容,可以自定义验证器:
import { FileValidator, Injectable } from '@nestjs/common'; @Injectable() export class CustomFileTypeValidator extends FileValidator { constructor(private readonly allowedExts: string[]) { super({}); } validate(file: any): boolean { // 检查文件名后缀 const nameExt = file.originalname.split('.').pop()?.toLowerCase() || ''; // 检查文件真实类型的扩展名(由file-type库识别) const realExt = file.ext?.toLowerCase() || ''; return this.allowedExts.includes(nameExt) && this.allowedExts.includes(realExt); } defaultMessage(): string { return `Validation failed (expected type is .(${this.allowedExts.join('|')}))`; } }
使用时替换原FileTypeValidator:
new CustomFileTypeValidator(['png','jpeg','jpg','pdf','gif','svg','mp4','psd','bmp','mov','avi']),
内容的提问来源于stack exchange,提问作者Shubham Ware
相关产品推荐
相关产品推荐

