NestJS 文件上传
为了处理文件上传,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,
});
例子
一个能够运行的样例在这里。
更多建议: