typescript 使用class-validator包为Nest.js上的图像上传创建自定义验证器

relj7zay  于 2023-02-05  发布在  TypeScript
关注(0)|答案(3)|浏览(239)

我想验证Nest.js中文件的mimetype,但我做不到。

@UseInterceptors(FileInterceptor('image'))
  @Post('upload_profile_photo')
  async uploadProfilePhoto(@UploadedFile() image: UploadImageDto) {
    return image;
}

UploadImageDto.ts

import { IsImageFile } from '../validators/IsImageFile';

export class UploadImageDto {
  @Validate(IsImageFile)
  mimetype: string;
}

IsImageFile.ts

@ValidatorConstraint({ async: false, name: 'image' })
export class IsImageFile implements ValidatorConstraintInterface {
  validate(mimeType: string, args: ValidationArguments) {
    // nothing is written on the console
    console.log(mimeType);

    const acceptMimeTypes = ['image/png', 'image/jpeg'];

    const fileType = acceptMimeTypes.find((type) => type === mimeType);

    if (!fileType) return false;

    return true;
  }

  defaultMessage(validationArguments?: ValidationArguments): string {
    return 'The file type was not accepted.';
  }
}

我的定制装饰器不好用。有人能帮帮我吗?

flvtvl50

flvtvl501#

您可以使用内置文件验证器

@UploadedFile(
    new ParseFilePipe({
        validators: [
            new FileTypeValidator({fileType: /\.(jpg|jpeg|png)$/}),
        ],
    })
)

注意:文件类型为RegExp
参见:https://docs.nestjs.com/techniques/file-upload#validators

ibps3vxo

ibps3vxo2#

您可以定义一个函数来执行验证,并在您希望验证的属性上方的注解中使用它,如下所示:

import { ValidationOptions, registerDecorator } from 'class-validator';

export function IsImageFile(options?: ValidationOptions) {
  return (object, propertyName: string) => {
    registerDecorator({
      target: object.constructor,
      propertyName,
      options,
      validator: {
        validate(mimeType) {
          const acceptMimeTypes = ['image/png', 'image/jpeg'];
          const fileType = acceptMimeTypes.find((type) => type === mimeType);
          return !fileType;
        },
      },
    });
  };
}
export class UploadImageDto {
  @IsImageFile({message: invalid mime type received})
  mimetype: string;
}
uelo1irk

uelo1irk3#

如果你需要使用FileInterceptor来验证上传文件的类型,它有fileFilter函数来帮助你在请求进来时捕获文件。第一个问题是它如何处理对FE的响应。一分钟后,我看到我们可以使用MulterError来处理响应中的这个错误。这是我的代码,希望它能有所帮助。

@Post('addOne')
  @UseInterceptors(
    FileInterceptor('image', {
      fileFilter: (req, file, cb) => {
        if (file.originalname.match(/^.*\.(jpg|webp|png|jpeg)$/))
          cb(null, true);
        else {
          cb(new MulterError('LIMIT_UNEXPECTED_FILE', 'image'), false);
        }
      },
      storage: diskStorage({
        destination: (req, file, cb) => {
          cb(null, join(__dirname, '..', '..', 'public/test'));
        },
        filename: (req, file, cb) => {
          cb(null, file.originalname);
        },
      }),
    }),
  }

如果你需要验证字段在请求时必须有文件。我们可以使用UploadedFile装饰器中的ParseFilePipe方法,它有fileIsRequired来帮助检查它。

@UploadedFile(
      new ParseFilePipe({
        fileIsRequired: true,
      }),
    )

相关问题