提问人:lumgaashi 提问时间:11/13/2023 更新时间:11/14/2023 访问量:46
Nestjs 图像验证
Nestjs Image Validation
问:
我创建了一个端点来上传头像,控制器是这样的:
@Post('/avatar')
@UseInterceptors(
FileInterceptor('file', {
storage: diskStorage({
destination: './public/avatars',
filename: (req, file, cb) => {
const { user } = req as unknown as { user: typeof ReqUser };
const { id } = user as unknown as { id: string };
const filename: string = id;
const extension: string = path.parse(file.originalname).ext;
cb(null, `${filename}${extension}`);
},
}),
}),
)
async uploadAvatar(
@UploadedFile(
new ParseFilePipe({
validators: [
new MaxFileSizeValidator({ maxSize: 5000000 }),
new FileTypeValidator({ fileType: /image\/(jpeg|png|jpg)/ }),
],
}),
)
file: Express.Multer.File,
@ReqUser() user,
) {
return this.meService.setAvatar(file, user);
}
我面临的问题是,如果文件无效,将抛出相应的错误,但文件将上传到服务器上,例如,它应该只允许上传带有 .jpg,png,jpg 扩展名的图像,但文件还是会上传?在这种情况下,我做错了什么?
答:
0赞
Jay McDoniel
11/14/2023
#1
拦截器在有机会运行其验证之前会完整地完成。您可以在异常筛选器中捕获错误,拉取并获取文件路径,然后在出现异常时删除文件。否则,您可以将文件加载到内存中,并仅在验证通过后才使用模块保存它ParseFilePipe
req.file
fs
0赞
Eranga Heshan
11/14/2023
#2
就像@jaymcdoniel解释的那样,拦截器将在代码执行函数之前运行。uploadAvatar
要停止将文件上传到服务器的存储,您可以使用 Multer 中的 fileFilter
选项。
@Post('/avatar')
@UseInterceptors(
FileInterceptor('file', {
fileFilter: (req, file, cb) => {
// Write your condition below based on the mimetype and/or filename extension.
if (<YOUR_CONDITION_TO_REJECT_THE_FILE>) {
cb(null, false);
} else {
cb(null, true);
}
},
storage: diskStorage({
destination: './public/avatars',
filename: (req, file, cb) => {
const { user } = req as unknown as { user: typeof ReqUser };
const { id } = user as unknown as { id: string };
const filename: string = id;
const extension: string = path.parse(file.originalname).ext;
cb(null, `${filename}${extension}`);
},
}),
})
)
async uploadAvatar(
...
这将防止 Multer 首先将文件保存在您的服务器中。这样,如果文件类型错误,则无需处理删除文件。
评论
0赞
lumgaashi
11/16/2023
我按照您的指示进行操作,确实有效,但似乎不知何故我有一个错误?因为我无法从 fileFilter 中的请求访问文件的大小。
0赞
Eranga Heshan
11/17/2023
很高兴能帮上忙。 理想情况下,参数应具有“文件信息”下提到的所有属性。当你说你无法访问时,你是什么意思?会返回吗?file
file.size
undefined
0赞
lumgaashi
11/17/2023
确切地说,它返回为 undefined,即使其中的文件显示它的大小。链接
0赞
Eranga Heshan
11/18/2023
看起来它们在filteFilter
函数中没有文件的
size
属性。您看到的是类型的属性,理想情况下应该对其进行修改以仅显示可用属性(这是其类型的问题)。无论如何,如果要限制文件大小,可以改用 property。limits
评论