Fayl yuklash
Fayl yuklashni boshqarish uchun Nest Express uchun multer middleware paketiga asoslangan ichki modulni taqdim etadi. Multer multipart/form-data formatida yuborilgan ma'lumotlarni q
Fayl yuklashni boshqarish uchun Nest Express uchun multer middleware paketiga asoslangan ichki modulni taqdim etadi. Multer multipart/form-data formatida yuborilgan ma'lumotlarni qayta ishlaydi, bu format asosan HTTP POST so'rovi orqali fayl yuklash uchun ishlatiladi. Bu modul to'liq sozlanadi va uning xatti-harakatini ilova talablariga moslab sozlashingiz mumkin.
Multer qo'llab-quvvatlanadigan multipart formatida (multipart/form-data) bo'lmagan ma'lumotlarni qayta ishlay olmaydi. Shuningdek, bu paket FastifyAdapter bilan mos emasligini unutmang.
Yaxshiroq tip xavfsizligi uchun Multer typings paketini o'rnatamiz:
1$ npm i -D @types/multerBu paket o'rnatilgach, Express.Multer.File turidan foydalanishimiz mumkin (bu turni quyidagicha import qilishingiz mumkin: import {{ '{' }} Express {{ '}' }} from 'express').
Asosiy misol
Bitta faylni yuklash uchun FileInterceptor() interceptorini marshrut handleriga bog'lang va @UploadedFile() dekoratori yordamida request ichidan file ni oling.
1@Post('upload')
2@UseInterceptors(FileInterceptor('file'))
3uploadFile(@UploadedFile() file: Express.Multer.File) {
4 console.log(file);
5}FileInterceptor() dekoratori @nestjs/platform-express paketidan eksport qilinadi. @UploadedFile() dekoratori @nestjs/common dan eksport qilinadi.
FileInterceptor() dekoratori ikki argument qabul qiladi:
fieldName: HTML formadagi fayl saqlanadigan maydon nomini ko'rsatadigan stringoptions:MulterOptionsturidagi ixtiyoriy obyekt. Bu multer konstruktorida ishlatiladigan xuddi shu obyekt (batafsil bu yerda).
FileInterceptor() Google Firebase kabi uchinchi tomon bulut provayderlari yoki boshqalari bilan mos kelmasligi mumkin.
Faylni validatsiya qilish
Ko'pincha kelayotgan fayl metama'lumotlarini, masalan fayl hajmi yoki MIME turi, tekshirish foydali bo'ladi. Buning uchun o'zingizning Pipe yaratib, uni UploadedFile dekoratori bilan belgilangan parametrga bog'lashingiz mumkin. Quyidagi misol oddiy fayl hajmi validator pipe qanday amalga oshirilishini ko'rsatadi:
1import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
2
3@Injectable()
4export class FileSizeValidationPipe implements PipeTransform {
5 transform(value: any, metadata: ArgumentMetadata) {
6 // "value" is an object containing the file's attributes and metadata
7 const oneKb = 1000;
8 return value.size < oneKb;
9 }
10}Buni FileInterceptor bilan birga quyidagicha ishlatish mumkin:
1@Post('file')
2@UseInterceptors(FileInterceptor('file'))
3uploadFileAndValidate(@UploadedFile(
4 new FileSizeValidationPipe(),
5 // other pipes can be added here
6) file: Express.Multer.File, ) {
7 return file;
8}Nest keng tarqalgan holatlarni qamrab olish va yangilarini qo'shishni osonlashtirish/standartlashtirish uchun ichki pipe taqdim etadi. Bu pipe ParseFilePipe deb ataladi va undan quyidagicha foydalanishingiz mumkin:
1@Post('file')
2uploadFileAndPassValidation(
3 @Body() body: SampleDto,
4 @UploadedFile(
5 new ParseFilePipe({
6 validators: [
7 // ... Set of file validator instances here
8 ]
9 })
10 )
11 file: Express.Multer.File,
12) {
13 return {
14 body,
15 file: file.buffer.toString(),
16 };
17}Ko'rib turganingizdek, ParseFilePipe bajaradigan fayl validatorlari massivini ko'rsatish talab qilinadi. Validator interfeysi haqida keyinroq gaplashamiz, ammo bu pipe yana ikki ixtiyoriy parametrga ega ekanini aytib o'tish kerak:
errorHttpStatusCode | Har qanday validator muvaffaqiyatsiz bo'lsa, tashlanadigan HTTP status kodi. Standarti 400 (BAD REQUEST) |
exceptionFactory | Xato xabarini qabul qilib, xatoni qaytaradigan factory. |
Endi FileValidator interfeysiga qaytamiz. Validatorlarni bu pipe bilan integratsiya qilish uchun siz ichki implementatsiyalardan foydalanishingiz yoki o'zingizning FileValidator ni taqdim etishingiz kerak. Quyidagi misolga qarang:
1export abstract class FileValidator<TValidationOptions = Record<string, any>> {
2 constructor(protected readonly validationOptions: TValidationOptions) {}
3
4 /**
5 * Indicates if this file should be considered valid, according to the options passed in the constructor.
6 * @param file the file from the request object
7 */
8 abstract isValid(file?: any): boolean | Promise<boolean>;
9
10 /**
11 * Builds an error message in case the validation fails.
12 * @param file the file from the request object
13 */
14 abstract buildErrorMessage(file: any): string;
15}FileValidator interfeysi isValid funksiyasi orqali async validatsiyani qo'llab-quvvatlaydi. Tip xavfsizligidan foydalanish uchun, agar driver sifatida express (default) ishlatayotgan bo'lsangiz, file parametrini Express.Multer.File sifatida tiplashingiz ham mumkin.
FileValidator oddiy klass bo'lib, fayl obyektiga kirish huquqiga ega va mijoz taqdim etgan variantlarga ko'ra uni tekshiradi. Nestda loyihangizda ishlatishingiz mumkin bo'lgan ikkita ichki FileValidator implementatsiyasi mavjud:
MaxFileSizeValidator- berilgan fayl hajmi ko'rsatilgan qiymatdan kichikligini tekshiradi (bytesda o'lchanadi)FileTypeValidator- berilgan faylning MIME turini berilgan satr yoki RegExp bilan mosligini tekshiradi. Default holatda MIME turini fayl kontentidagi magic number orqali tekshiradi
Yuqorida tilga olingan FileParsePipe bilan birga qanday ishlatilishini tushunish uchun, oxirgi misolning o'zgartirilgan parchasi bilan ko'rsatamiz:
1@UploadedFile(
2 new ParseFilePipe({
3 validators: [
4 new MaxFileSizeValidator({ maxSize: 1000 }),
5 new FileTypeValidator({ fileType: 'image/jpeg' }),
6 ],
7 }),
8)
9file: Express.Multer.File,Agar validatorlar soni ancha ko'payib ketsa yoki ularning opsiyalari faylni to'ldirib yuborsa, bu massivni alohida faylda aniqlab, bu yerda fileValidators kabi nomlangan konstanta sifatida import qilishingiz mumkin.
Nihoyat, validatorlarni tuzish va kompozitsiya qilish imkonini beradigan maxsus ParseFilePipeBuilder klassidan foydalanishingiz mumkin. Quyida ko'rsatilgandek ishlatsangiz, har bir validatorni qo'lda yaratishdan qochib, ularning opsiyalarini bevosita uzatasiz:
1@UploadedFile(
2 new ParseFilePipeBuilder()
3 .addFileTypeValidator({
4 fileType: 'jpeg',
5 })
6 .addMaxSizeValidator({
7 maxSize: 1000
8 })
9 .build({
10 errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY
11 }),
12)
13file: Express.Multer.File,Fayl mavjudligi default bo'yicha talab qilinadi, ammo build funksiyasi opsiyalarida (xuddi errorHttpStatusCode bilan bir xil darajada) fileIsRequired: false parametrini qo'shib, uni ixtiyoriy qilishingiz mumkin.
Fayllar massivi
Bitta maydon nomi bilan aniqlanadigan fayllar massivini yuklash uchun FilesInterceptor() dekoratoridan foydalaning (dekorator nomidagi ko'plik Files ga e'tibor bering). Bu dekorator uchta argument qabul qiladi:
fieldName: yuqorida tasvirlanganidekmaxCount: qabul qilinadigan maksimal fayllar sonini belgilovchi ixtiyoriy sonoptions: yuqorida ta'riflanganidek ixtiyoriyMulterOptionsobyekti
FilesInterceptor() dan foydalanganda, @UploadedFiles() dekoratori orqali request ichidan fayllarni oling.
1@Post('upload')
2@UseInterceptors(FilesInterceptor('files'))
3uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
4 console.log(files);
5}FilesInterceptor() dekoratori @nestjs/platform-express paketidan eksport qilinadi. @UploadedFiles() dekoratori @nestjs/common dan eksport qilinadi.
Bir nechta fayl
Bir nechta faylni (har biri turli maydon nomlari bilan) yuklash uchun FileFieldsInterceptor() dekoratoridan foydalaning. Bu dekorator ikki argument qabul qiladi:
uploadedFields: obyektlar massivi bo'lib, har bir obyekt yuqorida ta'riflanganidek maydon nomini ko'rsatadigannamexossasiga ega bo'lishi shart, hamda ixtiyoriymaxCountxossasiga ega bo'lishi mumkinoptions: yuqorida ta'riflanganidek ixtiyoriyMulterOptionsobyekti
FileFieldsInterceptor() dan foydalanganda, @UploadedFiles() dekoratori orqali request ichidan fayllarni oling.
1@Post('upload')
2@UseInterceptors(FileFieldsInterceptor([
3 { name: 'avatar', maxCount: 1 },
4 { name: 'background', maxCount: 1 },
5]))
6uploadFile(@UploadedFiles() files: { avatar?: Express.Multer.File[], background?: Express.Multer.File[] }) {
7 console.log(files);
8}Ixtiyoriy fayllar
Ixtiyoriy maydon nomlari bilan barcha maydonlarni yuklash uchun AnyFilesInterceptor() dekoratoridan foydalaning. Bu dekorator yuqorida ta'riflanganidek ixtiyoriy options obyektini qabul qilishi mumkin.
AnyFilesInterceptor() dan foydalanganda, @UploadedFiles() dekoratori orqali request ichidan fayllarni oling.
1@Post('upload')
2@UseInterceptors(AnyFilesInterceptor())
3uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
4 console.log(files);
5}Faylsiz
multipart/form-data ni qabul qilib, lekin hech qanday fayl yuklashga ruxsat bermaslik uchun NoFilesInterceptor dan foydalaning. Bu multipart ma'lumotlarni request body atributlari sifatida o'rnatadi. So'rov bilan yuborilgan istalgan fayl BadRequestException ni chiqaradi.
1@Post('upload')
2@UseInterceptors(NoFilesInterceptor())
3handleMultiPartData(@Body() body) {
4 console.log(body)
5}Standart parametrlar
Yuqorida ta'riflanganidek, fayl interceptorslarida multer opsiyalarini ko'rsatishingiz mumkin. Standart opsiyalarni o'rnatish uchun MulterModule ni import qilayotganingizda statik register() metodini chaqirib, qo'llab-quvvatlanadigan opsiyalarni uzatishingiz mumkin. Bu yerda keltirilgan barcha opsiyalardan foydalanishingiz mumkin.
1MulterModule.register({
2 dest: './upload',
3});MulterModule klassi @nestjs/platform-express paketidan eksport qilinadi.
Async sozlash
MulterModule opsiyalarini statik emas, asinxron tarzda o'rnatishingiz kerak bo'lganda registerAsync() metodidan foydalaning. Aksariyat dinamik modullar kabi, Nest asinxron konfiguratsiya uchun bir nechta usullarni taqdim etadi.
Usullardan biri - factory funksiyasidan foydalanish:
1MulterModule.registerAsync({
2 useFactory: () => ({
3 dest: './upload',
4 }),
5});Boshqa factory providerlar kabi, factory funksiyamiz async bo'lishi va inject orqali bog'liqliklarni qabul qilishi mumkin.
1MulterModule.registerAsync({
2 imports: [ConfigModule],
3 useFactory: async (configService: ConfigService) => ({
4 dest: configService.get<string>('MULTER_DEST'),
5 }),
6 inject: [ConfigService],
7});Muqobil ravishda, quyida ko'rsatilganidek, MulterModule ni factory o'rniga klass yordamida sozlashingiz mumkin:
1MulterModule.registerAsync({
2 useClass: MulterConfigService,
3});Yuqoridagi konstruktsiya MulterConfigService ni MulterModule ichida yaratadi va undan kerakli opsiyalar obyektini yaratish uchun foydalanadi. E'tibor bering, bu misolda MulterConfigService MulterOptionsFactory interfeysini implementatsiya qilishi kerak, bu quyida ko'rsatilgan. MulterModule taqdim etilgan klass obyektining createMulterOptions() metodini chaqiradi.
1@Injectable()
2class MulterConfigService implements MulterOptionsFactory {
3 createMulterOptions(): MulterModuleOptions {
4 return {
5 dest: './upload',
6 };
7 }
8}Agar MulterModule ichida private nusxa yaratmasdan mavjud opsiyalar providerni qayta ishlatmoqchi bo'lsangiz, useExisting sintaksisidan foydalaning.
1MulterModule.registerAsync({
2 imports: [ConfigModule],
3 useExisting: ConfigService,
4});Shuningdek, registerAsync() metodiga extraProviders deb ataladigan providerlarni uzatishingiz mumkin. Bu providerlar modul providerlari bilan birlashtiriladi.
1MulterModule.registerAsync({
2 imports: [ConfigModule],
3 useClass: ConfigService,
4 extraProviders: [MyAdditionalProvider],
5});Bu factory funksiyasi yoki klass konstruktori uchun qo'shimcha bog'liqliklar taqdim etmoqchi bo'lganingizda foydali.
Misol
Ishlaydigan misol bu yerda mavjud.