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

NestJS FileTypeValidator兼容XLSX但不兼容CSV,需同时支持两者

NestJS 配置 FileTypeValidator 同时支持 CSV 和 XLSX 文件

问题场景

使用 NestJS 的 FileTypeValidator 验证上传文件时,.xlsx 文件能正常通过验证,但 .csv 文件(MIME 为 text/csv)验证失败。当前验证代码如下:

@UploadedFile(
  new ParseFilePipe({
    validators: [
      new FileTypeValidator({
        fileType:
          /^(text\/csv|application\/vnd\.openxmlformats-officedocument\.spreadsheetml\.sheet)$/,
      }),
    ],
    fileIsRequired: true,
  }),
)

调试日志显示上传文件的 MIME 类型:

DEBUG : text/csv Untitled spreadsheet.csv
DEBUG : application/vnd.openxmlformats-officedocument.spreadsheetml.sheet test.xlsx

问题原因

FileTypeValidator 底层依赖 file-type 库,该库通过文件内容的魔术字节识别 MIME 类型,而非仅依赖请求头或文件名。CSV 属于纯文本文件,没有特定的魔术字节,因此 file-type 会将其识别为 text/plain,而非请求头中的 text/csv,导致正则匹配失败。

解决方案

方案1:调整正则并结合扩展名验证

修改正则表达式兼容 text/plain,同时添加自定义验证器检查文件扩展名,避免误判其他纯文本文件:

import { FileValidator, ParseFilePipe, UploadedFile } from '@nestjs/common';

// 自定义扩展名验证器
class FileExtensionValidator extends FileValidator {
  constructor(private readonly allowedExtensions: string[]) {
    super({});
  }

  isValid(file: Express.Multer.File): boolean {
    const fileExtension = file.originalname.split('.').pop().toLowerCase();
    return this.allowedExtensions.includes(fileExtension);
  }

  buildErrorMessage(): string {
    return `文件扩展名必须是 ${this.allowedExtensions.join(', ')}`;
  }
}

// 使用验证器
@UploadedFile(
  new ParseFilePipe({
    validators: [
      new FileTypeValidator({
        fileType: /^(text\/csv|text\/plain|application\/vnd\.openxmlformats-officedocument\.spreadsheetml\.sheet)$/,
      }),
      new FileExtensionValidator(['csv', 'xlsx']),
    ],
    fileIsRequired: true,
  }),
)

方案2:自定义验证器同时校验 MIME 和扩展名

直接自定义验证器,同时检查请求头中的 MIME 类型和文件扩展名,摆脱对 FileTypeValidator 的依赖:

import { FileValidator, ParseFilePipe, UploadedFile } from '@nestjs/common';

class SpreadsheetFileValidator extends FileValidator {
  private readonly allowedMimes = [
    'text/csv',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  ];
  private readonly allowedExtensions = ['csv', 'xlsx'];

  isValid(file: Express.Multer.File): boolean {
    const isValidMime = this.allowedMimes.includes(file.mimetype);
    const fileExtension = file.originalname.split('.').pop().toLowerCase();
    const isValidExtension = this.allowedExtensions.includes(fileExtension);
    return isValidMime && isValidExtension;
  }

  buildErrorMessage(): string {
    return `仅支持上传 CSV 和 XLSX 文件`;
  }
}

// 使用验证器
@UploadedFile(
  new ParseFilePipe({
    validators: [new SpreadsheetFileValidator()],
    fileIsRequired: true,
  }),
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 16:20:06