Nestjs: Image uploaded even if body validation fails

北城以北 提交于 2020-05-13 09:19:09

问题


First of all, I apologize for my weak English.

I have a method that accepts PUT request, and it receives a file and BlogModel. When I submit the form from frontend and the BlogModel's validation is failed the file is still uploaded.

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 method


  @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>

I expect the file is not uploaded if the validation is failed.


回答1:


What's happening here has to do with the Execution order of the NestJS Request Cycle, namely, how interceptors are called and fired before pipes are. In this case, you are calling the file upload interceptor, letting that code run as needed, and then validating your payload, so even if you have an invalid payload you are still uploading the file. You can view the file upload interceptor here and see what that code looks like. If you absolutely need the file upload and payload to be in the same request, you could always create your own validation interceptor instead of pipe and run this validation before the file upload interceptor. Otherwise you can make them two separate requests.




回答2:


Had the same problem, what I ended up doing was manually validating the field before calling my service,

Implementing an interceptor just to validate the file seems overkill.

    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');
        }



来源:https://stackoverflow.com/questions/58477104/nestjs-image-uploaded-even-if-body-validation-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!