為了處理文件上傳,Nest 提供了一個(gè)內(nèi)置的基于 multer 中間件包的 Express 模塊。Multer 處理以 multipart/form-data 格式發(fā)送的數(shù)據(jù),該格式主要用于通過(guò) HTTP POST 請(qǐng)求上傳文件。這個(gè)模塊是完全可配置的,您可以根據(jù)您的應(yīng)用程序需求調(diào)整它的行為。
Multer無(wú)法處理不是受支持的多部分格式( multipart/form-data )的數(shù)據(jù)。 另外,請(qǐng)注意此程序包與 FastifyAdapter 不兼容。
為了更好的類型安全,我們來(lái)安裝 Multer 的類型聲明包:
$ npm i -D @types/multer
只要這個(gè)模塊被安裝,我們就可以使用 Express.Multer.File 這個(gè)類型(你可以通過(guò) import { Express } from 'express' 導(dǎo)入這個(gè)類型)。
當(dāng)我們要上傳單個(gè)文件時(shí), 我們只需將 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() 接收兩個(gè)參數(shù):
FileInterceptor() 可能不兼容諸如 Google Firebase 之類的第三方云服務(wù)商。
為了上傳文件數(shù)組,我們使用 FilesInterceptor()。請(qǐng)使用 FilesInterceptor() 裝飾器(注意裝飾器名稱中的復(fù)數(shù)文件)。這個(gè)裝飾器有三個(gè)參數(shù):
使用 FilesInterceptor() 時(shí),使用 @UploadedFiles() 裝飾器從 request 中提取文件。
@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
console.log(files);
}
FilesInterceptor() 裝飾器是 @nestjs/platform-express 包提供的, @UploadedFiles() 裝飾器是 @nestjs/common 包提供的。
要上傳多個(gè)文件(全部使用不同的鍵),請(qǐng)使用 FileFieldsInterceptor() 裝飾器。這個(gè)裝飾器有兩個(gè)參數(shù):
使用 FileFieldsInterceptor() 時(shí),使用 @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);
}
要使用任意字段名稱鍵上載所有字段,請(qǐng)使用 AnyFilesInterceptor() 裝飾器。該裝飾器可以接受如上所述的可選選項(xiàng)對(duì)象。
使用 AnyFilesInterceptor() 時(shí),使用 @UploadedFiles() 裝飾器從 request 中提取文件。
@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
console.log(files);
}
您可以像上面描述的那樣在文件攔截器中指定 multer 選項(xiàng)。要設(shè)置默認(rèn)選項(xiàng),可以在導(dǎo)入 MulterModule 時(shí)調(diào)用靜態(tài) register() 方法,傳入受支持的選項(xiàng)。您可以使用這里列出的所有選項(xiàng)。
MulterModule.register({
dest: '/upload',
});
MulterModule 類是 @nestjs/platform-express 包提供的。
當(dāng)需要異步而不是靜態(tài)地設(shè)置 MulterModule 選項(xiàng)時(shí),請(qǐng)使用 registerAsync() 方法。與大多數(shù)動(dòng)態(tài)模塊一樣,Nest 提供了一些處理異步配置的技術(shù)。
第一種可能的方法是使用工廠函數(shù):
MulterModule.registerAsync({
useFactory: () => ({
dest: '/upload',
}),
});
與其他工廠提供程序一樣,我們的工廠函數(shù)可以是異步的,并且可以通過(guò) inject 選項(xiàng)注入依賴。
MulterModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
dest: configService.getString('MULTER_DEST'),
}),
inject: [ConfigService],
});
或者,您可以使用類而不是工廠來(lái)配置 MulterModule,如下所示:
MulterModule.registerAsync({
useClass: MulterConfigService,
});
上面的構(gòu)造在 MulterModule 中實(shí)例化 MulterConfigService ,使用它來(lái)創(chuàng)建所需的選項(xiàng)對(duì)象。注意,在本例中,MulterConfigService 必須實(shí)現(xiàn) MulterOptionsFactory 接口,如下所示。MulterModule 將在提供的類的實(shí)例化對(duì)象上調(diào)用 createMulterOptions() 方法。
@Injectable()
class MulterConfigService implements MulterOptionsFactory {
createMulterOptions(): MulterModuleOptions {
return {
dest: '/upload',
};
}
}
如果你想要重復(fù)使用一個(gè)已經(jīng)存在的選項(xiàng)提供者而不是在 MulterModule 內(nèi)創(chuàng)建一個(gè)私有的拷貝,使用 useExisting 語(yǔ)法。
MulterModule.registerAsync({
imports: [ConfigModule],
useExisting: ConfigService,
});
一個(gè)能夠運(yùn)行的樣例在這里。
更多建議: