NestJS 文件上传

2023-09-08 18:11 更新

为了处理文件上传,Nest 提供了一个内置的基于 multer 中间件包的 Express 模块。Multer 处理以 multipart/form-data 格式发送的数据,该格式主要用于通过 HTTP POST 请求上传文件。这个模块是完全可配置的,您可以根据您的应用程序需求调整它的行为。

Multer无法处理不是受支持的多部分格式( multipart/form-data )的数据。 另外,请注意此程序包与 FastifyAdapter 不兼容。

为了更好的类型安全,我们来安装 Multer 的类型声明包:

$ npm i -D @types/multer

只要这个模块被安装,我们就可以使用 Express.Multer.File 这个类型(你可以通过 import { Express } from 'express' 导入这个类型)。

基本实例

当我们要上传单个文件时, 我们只需将 FileInterceptor() 与处理程序绑定在一起, 然后使用 @UploadedFile() 装饰器从 request 中取出 file。

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file);
}

FileInterceptor() 装饰器是 @nestjs/platform-express 包提供的, @UploadedFile() 装饰器是 @nestjs/common 包提供的。

FileInterceptor() 接收两个参数:

  • 一个 fieldName (指向包含文件的 HTML 表单的字段)
  • 可选 options 对象, 类型为 MulterOptions 。这个和被传入 multer 构造函数 (此处有更多详细信息) 的对象是同一个对象。

FileInterceptor() 可能不兼容诸如 Google Firebase 之类的第三方云服务商。

文件数组

为了上传文件数组,我们使用 FilesInterceptor()。请使用 FilesInterceptor() 装饰器(注意装饰器名称中的复数文件)。这个装饰器有三个参数:

  • fieldName:(保持不变)
  • maxCount:可选的数字,定义要接受的最大文件数
  • options:可选的 MulterOptions 对象 ,如上所述

使用 FilesInterceptor() 时,使用 @UploadedFiles() 装饰器从 request 中提取文件。

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}

FilesInterceptor() 装饰器是 @nestjs/platform-express 包提供的, @UploadedFiles() 装饰器是 @nestjs/common 包提供的。

多个文件

要上传多个文件(全部使用不同的键),请使用 FileFieldsInterceptor() 装饰器。这个装饰器有两个参数:

  • uploadedFields:对象数组,其中每个对象指定一个必需的 name 属性和一个指定字段名的字符串值(如上所述),以及一个可选的 maxCount 属性(如上所述)
  • options: 可选的 MulterOptions 对象,如上所述

使用 FileFieldsInterceptor() 时,使用 @UploadedFiles() 装饰器从 request 中提取文件。

@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { avatar?: Express.Multer.File[], background?: Express.Multer.File[] }) {
  console.log(files);
}

任何文件

要使用任意字段名称键上载所有字段,请使用 AnyFilesInterceptor() 装饰器。该装饰器可以接受如上所述的可选选项对象。

使用 AnyFilesInterceptor() 时,使用 @UploadedFiles() 装饰器从 request 中提取文件。

@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}

默认选项

您可以像上面描述的那样在文件拦截器中指定 multer 选项。要设置默认选项,可以在导入 MulterModule 时调用静态 register() 方法,传入受支持的选项。您可以使用这里列出的所有选项。

MulterModule.register({
  dest: '/upload',
});

MulterModule 类是 @nestjs/platform-express 包提供的。

异步配置

当需要异步而不是静态地设置 MulterModule 选项时,请使用 registerAsync() 方法。与大多数动态模块一样,Nest 提供了一些处理异步配置的技术。

第一种可能的方法是使用工厂函数:

MulterModule.registerAsync({
  useFactory: () => ({
    dest: '/upload',
  }),
});

与其他工厂提供程序一样,我们的工厂函数可以是异步的,并且可以通过 inject 选项注入依赖。

MulterModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    dest: configService.getString('MULTER_DEST'),
  }),
  inject: [ConfigService],
});

或者,您可以使用类而不是工厂来配置 MulterModule,如下所示:

MulterModule.registerAsync({
  useClass: MulterConfigService,
});

上面的构造在 MulterModule 中实例化 MulterConfigService ,使用它来创建所需的选项对象。注意,在本例中,MulterConfigService 必须实现 MulterOptionsFactory 接口,如下所示。MulterModule 将在提供的类的实例化对象上调用 createMulterOptions() 方法。

@Injectable()
class MulterConfigService implements MulterOptionsFactory {
  createMulterOptions(): MulterModuleOptions {
    return {
      dest: '/upload',
    };
  }
}

如果你想要重复使用一个已经存在的选项提供者而不是在 MulterModule 内创建一个私有的拷贝,使用 useExisting 语法。

MulterModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});

例子

一个能够运行的样例在这里


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号