Загрузка файла NestJS с помощью multer

Published on
Authors

В этом руководстве мы узнаем, как загружать изображения в приложение nestjs с помощью multer. Рассмотрим 3 основных момента (для загрузки файлов NestJS с помощью multer):

  • Загрузка одно изображение
  • Загрузка нескольких изображений
  • получить изображение, используя сохраненное имя изображения
  • Проверка типа загружаемых файлов, только изображения (расширения .jpg, .png etc.)

Итак, теперь начнем с создания нового демонстрационного проекта nestjs.

ШАГ 1. Создание проекта Nest.js

$ nest new file-upload-demo$ cd file-upload-demo

ШАГ 2: Установите зависимости

$ npm install @nestjs/platform-express --save
$ npm install @types/express -D
$ npm install

ШАГ 3: Создание логики проверки файла

Теперь мы создадим файл, который содержит внутри логику, связанную с проверкой файла, для этого выполните следующую команду:

$ mkdir src/utils$ touch src/utils/file-upload.utils.ts

Теперь откройте файл src/utils/file-upload.ts и обновите в нем следующий код:

import { extname } from 'path';
import { HttpException, HttpStatus } from '@nestjs/common';
// Разрешить только изображения
export const imageFileFilter = (req, file, callback) => {
  if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
    return callback(
      new HttpException(
        'Only image files are allowed!',
        HttpStatus.BAD_REQUEST,
      ),
      false,
    );
  }
  callback(null, true);
};
export const editFileName = (req, file, callback) => {
  const name = file.originalname.split('.')[0];
  const fileExtName = extname(file.originalname);
  const randomName = Array(4)
    .fill(null)
    .map(() => Math.round(Math.random() * 10).toString(10))
    .join('');
  callback(null, `${name}${randomName}${fileExtName}`);
};

ШАГ 4: Создание файловых модулей

Откройте новый терминал и выполните следующую команду:

$ nest g module files

Команда создаст файл src/files/files.module.ts, откроет этот файл и вставит в него следующий код:

import { Module } from '@nestjs/common';
import { FilesController } from './files.controller';
@Module({
  controllers: [FilesController]
})
export class FilesModule {}

сразу после этого откройте файл src/app.module.ts и добавьте filesModule и multerModule, которые в дальнейшем будут использоваться для загрузки файлов, теперь обновленный файл src/app.module.ts будет выглядеть так:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MulterModule } from '@nestjs/platform-express';
import { FilesModule } from './files/files.module';
@Module({
  imports: [
    MulterModule.register({
      dest: './uploads',
    }),
    FilesModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

ШАГ 5: Генерация файлового контроллера

Это последний шаг этого процесса, filesController содержит всю логику, связанную с загрузкой изображения (одного и более), а также извлечением сохраненного изображения.

Выполните следующую команду, чтобы сгенерировать файловый контроллер:

$ nest g controller files

откройте этот файл и обновите в нем следующий код:

import { Controller, Get, Post,UseInterceptors, UploadedFile, UploadedFiles, Res, Param, HttpStatus } from '@nestjs/common';
import { FileInterceptor, FilesInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { editFileName, imageFileFilter } from '../utils/file-upload.utils';
@Controller('files')
export class FilesController {
  constructor() {}
  // upload single file
  @Post()
  @UseInterceptors(
    FileInterceptor('image', {
      storage: diskStorage({
        destination: './uploads',
        filename: editFileName,
      }),
      fileFilter: imageFileFilter,
    }),
  )
  async uploadedFile(@UploadedFile() file) {
    const response = {
      originalname: file.originalname,
      filename: file.filename,
    };
    return {
      status: HttpStatus.OK,
      message: 'Image uploaded successfully!',
      data: response,
    };
  }
  @Post('uploadMultipleFiles')
  @UseInterceptors(
    FilesInterceptor('image', 10, {
      storage: diskStorage({
        destination: './uploads',
        filename: editFileName,
      }),
      fileFilter: imageFileFilter,
    }),
  )
  async uploadMultipleFiles(@UploadedFiles() files) {
    const response = [];
    files.forEach(file => {
      const fileReponse = {
        originalname: file.originalname,
        filename: file.filename,
      };
      response.push(fileReponse);
    });
    return {
      status: HttpStatus.OK,
      message: 'Images uploaded successfully!',
      data: response,
    };
  }
  @Get(':imagename')
  getImage(@Param('imagename') image, @Res() res) {
    const response = res.sendFile(image, { root: './uploads' });
    return {
      status: HttpStatus.OK,
      data: response,
    };
  }
}

В filesController есть 3 метода, первый метод uploadedFile() с декоратором @Post() предназначен для загрузки одного изображения за раз. FileInterceptor() принимает 2 параметра, первый — это ключ запроса (полезная нагрузка), который содержит данные изображения, второй — объект, который содержит такие параметры, как путь к каталогу для сохранения мультимедийного изображения, fileFilter и т. Здесь каталог хранения uploads находится в корне папки проекта.

Второй метод uploadMultipleFiles() может загружать более одного файла за раз, а FilesInterceptor() принимает 3 параметра: первый ключ payload, который содержит данные изображения, второй параметр для максимального количества файлов, разрешенных для загрузки за раз, и третий и последний — это объект, который содержит такие параметры, как путь к каталогу для сохранения изображения мультимедиа, фильтр файлов и т. д. Здесь снова каталог для хранения uploads находится в корне папки проекта.

Третий метод getImage() используется для получения сохраненного изображения, передавая имя изображения в URL-адресе.

Теперь снова запустите приложение (если оно запущено, сначала остановите), используя следующую команду:

$ npm run start

попробуйте загрузить неверный файл (а не изображение):

загрузить валидное изображение (одно):

загрузите несколько изображений:

получить загруженное изображение:

Заключение

Мы довели это все до конца! Я надеюсь, что эта статья помогла вам понять загрузку файлов в NestJS.