You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS如何验证多上传文件的总大小不超过限制?

NestJS多附件上传总大小限制与文件验证方案

一、基础配置:通过Multer限制单个文件大小

先在文件上传拦截器的配置里,设置单个文件的大小上限,同时可提前过滤非法文件类型:

import { Controller, Post, UploadedFiles, UseInterceptors } from '@nestjs/common';
import { FilesInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';

@Post('/text')
@UseInterceptors(FilesInterceptor('files', 10, { 
  // 第二个参数为允许上传的最大文件数量
  storage: diskStorage({
    destination: './uploads',
    filename: (req, file, cb) => {
      const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
      cb(null, `${file.fieldname}-${uniqueSuffix}`);
    },
  }),
  limits: {
    fileSize: 5 * 1024 * 1024, // 单个文件最大5MB(若总大小限制5MB,可设更小值)
  },
  fileFilter: (req, file, cb) => {
    // 过滤允许的文件MIME类型
    const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];
    if (allowedTypes.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new Error('仅允许上传JPG/PNG/PDF类型文件'), false);
    }
  },
}))
async addText(@UploadedFiles() files) {
  console.log("The files", files);
}

二、验证所有文件总大小不超过5MB

Multer无直接总大小限制配置,可通过自定义管道实现:

  1. 创建自定义验证管道FileTotalSizePipe:
import { PipeTransform, Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class FileTotalSizePipe implements PipeTransform {
  private readonly maxTotalSize = 5 * 1024 * 1024; // 5MB换算为字节

  transform(files: Express.Multer.File[]) {
    const totalSize = files.reduce((sum, file) => sum + file.size, 0);
    if (totalSize > this.maxTotalSize) {
      throw new BadRequestException(`所有文件总大小不能超过5MB`);
    }
    return files;
  }
}
  1. 在接口中引入该管道:
@Post('/text')
@UseInterceptors(FilesInterceptor('files', 10, {
  // 保留之前的multer配置
}))
async addText(@UploadedFiles(FileTotalSizePipe) files) {
  console.log("The files", files);
}

三、扩展多维度文件验证

如果需要更全面的校验(比如文件数量、单个文件二次校验、扩展名验证),可扩展管道逻辑:

import { PipeTransform, Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class FullFileValidationPipe implements PipeTransform {
  private readonly maxTotalSize = 5 * 1024 * 1024;
  private readonly maxSingleSize = 2 * 1024 * 1024; // 单个文件最大2MB
  private readonly maxFileCount = 5; // 最多上传5个文件
  private readonly allowedExtensions = ['.jpg', '.jpeg', '.png', '.pdf'];

  transform(files: Express.Multer.File[]) {
    // 验证文件数量
    if (files.length > this.maxFileCount) {
      throw new BadRequestException(`最多允许上传${this.maxFileCount}个文件`);
    }

    // 单个文件大小与扩展名校验
    files.forEach(file => {
      if (file.size > this.maxSingleSize) {
        throw new BadRequestException(`文件${file.originalname}大小不能超过2MB`);
      }
      const ext = file.originalname.toLowerCase().slice(file.originalname.lastIndexOf('.'));
      if (!this.allowedExtensions.includes(ext)) {
        throw new BadRequestException(`文件${file.originalname}类型不允许,仅支持${this.allowedExtensions.join(', ')}`);
      }
    });

    // 总大小校验
    const totalSize = files.reduce((sum, file) => sum + file.size, 0);
    if (totalSize > this.maxTotalSize) {
      throw new BadRequestException(`所有文件总大小不能超过5MB`);
    }

    return files;
  }
}

之后在接口中替换使用FullFileValidationPipe即可。

内容的提问来源于stack exchange,提问作者Zephyr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 00:40:39