【问题标题】:Nestjs: Image uploaded even if body validation failsNestjs:即使正文验证失败也上传图片
【发布时间】:2020-02-17 00:00:38
【问题描述】:

首先,我很抱歉我的英语不好。

我有一个接受 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();

添加博客方法


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

如果验证失败,我希望文件不会上传。

【问题讨论】:

标签: javascript nestjs


【解决方案1】:

遇到同样的问题,我最终做的是在调用我的服务之前手动验证字段,

实施拦截器只是为了验证文件似乎有点过头了。

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

【讨论】:

    【解决方案2】:

    这里发生的事情与 NestJS 请求周期的执行顺序有关,即在管道之前如何调用和触发拦截器。在这种情况下,您正在调用文件上传拦截器,让该代码根据需要运行,然后验证您的有效负载,因此即使您的有效负载无效,您仍在上传文件。你can view the file upload interceptor here 看看那个代码是什么样子的。如果您绝对需要文件上传和有效负载在同一个请求中,您始终可以创建自己的验证拦截器而不是管道并在文件上传拦截器之前运行此验证。否则,您可以向它们发出两个单独的请求。

    【讨论】:

      猜你喜欢
      • 2018-12-15
      • 2022-11-22
      • 1970-01-01
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      • 2014-01-13
      • 2010-10-19
      • 2018-07-02
      相关资源
      最近更新 更多