首先,我为我的英语薄弱而道歉。
我有一个接受PUT请求的方法,它接收文件和BlogModel。当我从前端提交表单并且BlogModel的验证失败时,该文件仍会上传。
main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './core/app.module';
import { ValidationPipe } from '@nestjs/common';
import { join } from 'path';
import { NestExpressApplication } from '@nestjs/platform-express';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useStaticAssets(join(__dirname, '..', 'src/public'));
app.setBaseViewsDir(join(__dirname, '..', 'src/views'));
app.setViewEngine('hbs');
app.useGlobalPipes(new ValidationPipe());
await app.listen(3000);
}
bootstrap();
addBlog方法
@Put()
@UseInterceptors(FileInterceptor('thumbnail', { storage: BlogStorage }))
addBlog(@UploadedFile() file, @Body() addBlogModel: AddBlogModel) {
console.log(file);
}
add-blog.model.ts
import { IsArray, IsBoolean, IsNotEmpty, IsOptional, IsString, Length } from 'class-validator';
import { Expose } from 'class-transformer';
export class AddBlogModel {
@IsNotEmpty()
@IsString()
title: string;
@IsString()
@Length(10, 225)
@IsOptional()
introduction: string;
@IsNotEmpty()
@IsString()
content: string;
@IsBoolean()
@Expose({name: 'is_published'})
isPublished: boolean;
@IsArray()
@IsNotEmpty()
tags: string[];
@IsString()
@IsNotEmpty()
category: string;
}
index.hbs
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form id="form">
<input name="title" id="title"/>
<input name="content" id="content"/>
<input type="file" name="thumbnail" id="thumbnail"/>
<button type="submit">Submit</button>
</form>
<script src="https://code.jquery.com/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#form").on('submit', function (e) {
e.preventDefault();
const data = $(this).serializeArray()
const data_from_array = {}
var formData = new FormData()
$.map(data, function(n, i){
formData.append(n['name'], n['value'])
});
const file = $('input[type="file"]')[0].files[0]
formData.append('thumbnail', file)
const config = {
headers: {
'content-type': 'multipart/form-data'
}
}
axios.put('http://localhost:3000/blogs', formData, config).then(res => {
console.log(res)
}).catch(err => {
console.log(err.response)
})
});
})
</script>
</body>
</html>
如果验证失败,我希望文件不会上传。
答案 0 :(得分:0)
这里发生的事情与NestJS请求周期的执行顺序有关,即,在管道到达之前如何调用和触发拦截器。在这种情况下,您将调用文件上传拦截器,让该代码根据需要运行,然后验证您的有效负载,因此,即使您有无效的有效负载,您仍在上传文件。您can view the file upload interceptor here,然后查看该代码的外观。如果绝对需要文件上传和有效负载在同一请求中,则可以始终创建自己的验证拦截器而不是管道,并在文件上传拦截器之前运行此验证。否则,您可以向他们提出两个单独的请求。
答案 1 :(得分:0)
遇到同样的问题,我最终要做的是在致电服务之前手动验证该字段,
仅仅为了验证文件而实施拦截器似乎是过分的。
async createUser(@Response() res, @UploadedFile() avatar, @Body() user: CreateUserDTO) {
// FileUploads are not validated in the Pipe
if (_.isNil(avatar)) {
throw new BadRequestException(['avatar photo is required'], 'Validation Failed');
}