我创建了一个端点来上传头像,控制器如下:
@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扩展名的图像,但文件会无论如何都要上传吗?在这种情况下我做错了什么?
在
ParseFilePipe
有机会运行其验证之前,拦截器会完整地进行检查。您可以在异常过滤器中捕获错误,拉出 req.file
并获取文件路径,然后在异常时删除文件。否则,您可以将文件加载到内存中,并仅在验证通过后使用 fs
模块保存它
就像 @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 首先将文件保存到您的服务器中。这样,如果文件类型错误,您将不需要处理删除文件。