app.useGlobalPipes(new ValidationPipe({ whitelist: true })) 是 NestJS 中用于 全局启用数据验证和过滤 的配置。以下是其核心作用和关键细节:


核心作用

  1. 数据验证

    • 使用 class-validator 库对传入的请求体(如 @Body()@Query())进行验证,确保数据符合 DTO(数据传输对象)定义的规则(如类型、必填性等)。
    • 例如:@IsEmail()@MinLength(6) 等装饰器会触发对应验证。
  2. 数据转换

    • 使用 class-transformer 库将原始请求数据转换为 DTO 类的实例,确保类型匹配(如将字符串转换为数字)。
  3. 字段过滤(白名单机制)

    • whitelist: true 表示启用白名单模式,仅保留 DTO 类中显式声明的字段,过滤掉请求中未在 DTO 中定义的字段。

#### . class-validator 装饰器的作用

    • 字段的存在性检测

      • 如果字段未添加任何 class-validator 装饰器(如 @IsString()@IsOptional()),class-transformer 可能无法识别该字段,导致其被 whitelist 过滤。
    • 解决方案:即使字段不需要验证,也需添加 @IsOptional() 等装饰器。
    1. 非安全性要求高,不建议开启{ whitelist: true },会过滤未显性声明的字段,例如下面DTO遇到的坑

      // create-menu.dto.ts
      import { ApiProperty } from "@nestjs/swagger";
      import { IsNotEmpty, IsOptional } from "class-validator";
      
      export class CreateMenuDto {
        @IsNotEmpty({ message: '菜单标题不能为空' })
        @ApiProperty({ example: '菜单标题', description: '菜单标题' })
        title: string;
      
        @ApiProperty({ example: 1, description: '菜单排序' })
        order: number;
      
        @IsOptional()
        @ApiProperty({ example: 1, required: false, description: '父级菜单id' })
        parentId?: number;
      
        @ApiProperty({ example: 1, description: '菜单类型1:目录 2:菜单 3:按钮' })
      
        type: number;
      
        @ApiProperty({ example: 'icon', description: '菜单图标' })
        icon: string;
      
        @IsOptional()
        @ApiProperty({ example: 'AA/BB', required: false, description: '组件路径' })
        component?: string;
      
        @IsNotEmpty({ message: '路由不能为空' })
        @ApiProperty({ example: 'aa', description: '路由' })
        path: string;
      
        @ApiProperty({ example: 1, description: '创建者ID' })
        createBy: number;
      
        @IsOptional()
        @ApiProperty({ example: 'sys:post:list', required: false, description: '权限标识' })
        permission?: string;
      }
      
      5. ```
      

    发送数据

    {
      "title": "菜单标题",
      "order":"1",
      "parentId": 1,
      "type": 1,
      "icon": "icon",
      "component": "AA/BB",
      "path": "aa",
      "createBy": 1,
      "permission": "sys:post:list"
    }

    会返回

    {
        "title": "菜单标题",
        "parentId": 1,
        "component": "AA/BB",
        "path": "aa",
        "permission": "sys:post:list"
    }

    DTO中未使用class-validator声明的字段都会被过滤

    最后修改:2025 年 03 月 26 日
    如果觉得我的文章对你有用,请随意赞赏