Как правильно передать наименование файла в NestJS?
Всем привет! Возникла сложность с кодировкой наименования файлов. Теряется кириллица.
У меня приложение на expo. Я могу отправлять файлы при создании определенного элемента ( ниже функция ) :
export const updateTaskApi = async ( id: string, taskData: TTask, files: TDataFilePicker[] | null, ) => { const headers = await createHeaders(); headers['Content-Type'] = 'multipart/form-data'; console.log('headers', headers); const formData = new FormData(); formData.append('taskData', JSON.stringify(taskData)); if (files) { files.forEach((file) => { console.log(file); formData.append( 'files', { uri: file.filePickerUri, type: file.filePickerType, name: file.filePickerName, fileName: file.filePickerName, } as any, ); }); } console.log(formData); return await axios.put(`${basicUrl}/tasks`, formData, { withCredentials: true, headers, }); }; |
export const updateTaskApi = async ( id: string, taskData: TTask, files: TDataFilePicker[] | null, ) => { const headers = await createHeaders(); headers['Content-Type'] = 'multipart/form-data'; console.log('headers', headers); const formData = new FormData(); formData.append('taskData', JSON.stringify(taskData)); if (files) { files.forEach((file) => { console.log(file); formData.append( 'files', { uri: file.filePickerUri, type: file.filePickerType, name: file.filePickerName, fileName: file.filePickerName, } as any, ); }); } console.log(formData); return await axios.put(`${basicUrl}/tasks`, formData, { withCredentials: true, headers, }); };
Файлы уходят на бэк, но когда я их там разбираю , то вместо наименовании Аватар.jpg, я получаю просто .jpg и еще иногда с пустыми символами впереди.
Вот контроллер -
@Put() @HttpCode(HttpStatus.OK) @UseInterceptors(FilesInterceptor('files')) async updateTask( @Body() body: TaskFormData, @Req() request: Request, @UploadedFiles() files?: Array<Express.Multer.File>, ) { await verifyAuthorization(request); console.log('Request headers:', request.headers); if (!body.taskData) { throw new BadRequestException('Нету данных объекта задачи'); } console.log('files from general', files); const updateTask = plainToInstance(TaskDto, JSON.parse(body.taskData)); await this.tasksService.validateTaskPreparationData(updateTask); return await this.tasksService.updateTask( updateTask._id, updateTask, files, ); } |
@Put() @HttpCode(HttpStatus.OK) @UseInterceptors(FilesInterceptor('files')) async updateTask( @Body() body: TaskFormData, @Req() request: Request, @UploadedFiles() files?: Array<Express.Multer.File>, ) { await verifyAuthorization(request); console.log('Request headers:', request.headers); if (!body.taskData) { throw new BadRequestException('Нету данных объекта задачи'); } console.log('files from general', files); const updateTask = plainToInstance(TaskDto, JSON.parse(body.taskData)); await this.tasksService.validateTaskPreparationData(updateTask); return await this.tasksService.updateTask( updateTask._id, updateTask, files, ); }
В массиве файлов я вижу вот такое -
files from general [ { fieldname: 'files', originalname: '.jpg', encoding: '7bit', mimetype: 'image/jpeg', buffer: <Buffer ff d8 ff e2 0b f8 49 43 43 5f 50 52 4f 46 49 4c 45 00 01 01 00 00 0b e8 00 00 00 00 02 00 00 00 6d 6e 74 72 52 47 42 20 58 59 5a 20 07 d9 00 03 00 1b ... 72888 more bytes>, size: 72938 } ] |
files from general [ { fieldname: 'files', originalname: '.jpg', encoding: '7bit', mimetype: 'image/jpeg', buffer: <Buffer ff d8 ff e2 0b f8 49 43 43 5f 50 52 4f 46 49 4c 45 00 01 01 00 00 0b e8 00 00 00 00 02 00 00 00 6d 6e 74 72 52 47 42 20 58 59 5a 20 07 d9 00 03 00 1b ... 72888 more bytes>, size: 72938 } ]
Получается что поле originalname идет с ошибкой и потеряло кириллический текст. При этом из глобального, что могло бы влиять на запрос перед контроллером только валидация ( ValidationPipe ) и cookieParser . Больше ничего. уже сломал всю голову и не понимаю как быть с кодировкой и куда она исчезает.
Дополнительно:
Ответ кроется в этом объекте -
{ uri: file.filePickerUri, type: file.filePickerType, name: file.filePickerName, fileName: file.filePickerName, } as any, |
{ uri: file.filePickerUri, type: file.filePickerType, name: file.filePickerName, fileName: file.filePickerName, } as any,
Я был не прав что это не взаимосвязано. Достаточно name: file.filePickerName поменять на name: encodeURIComponent(file.filePickerName), а декодировать на стороне бэка и все будет корректно
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для передачи наименования файла в NestJS можно воспользоваться модулем multer, который позволяет обрабатывать многочисленные файлы, отправленные через форму. Вот пример того, как можно передать наименование файла в NestJS:
1. Установите модуль multer, если он еще не установлен, с помощью команды:
npm install --save @nestjs/platform-express multer
2. Импортируйте модуль MulterModule в вашем модуле приложения:
import { MulterModule } from '@nestjs/platform-express';
3. Добавьте MulterModule в раздел imports вашего модуля приложения, указав необходимые настройки:
MulterModule.register({ dest: './uploads', });
4. Создайте middleware для обработки загрузки файлов. Например, вот как может выглядеть middleware для загрузки одиночного файла:
import { Injectable, NestMiddleware } from '@nestjs/common'; import { Request, Response } from 'express'; import * as multer from 'multer'; @Injectable() export class FileUploadMiddleware implements NestMiddleware { private upload = multer({ dest: './uploads' }); use(req: Request, res: Response, next: Function) { this.upload.single('file')(req, res, next); } }
5. Зарегистрируйте созданный middleware в вашем модуле приложения:
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common'; @Module({ imports: [MulterModule], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(FileUploadMiddleware).forRoutes('upload'); } }
Теперь вы сможете передать наименование файла через форму загрузки файлов на вашем NestJS приложении. Не забудьте добавить обработку сохранения файла в нужное место в вашем контроллере или сервисе.