web-dev-qa-db-ja.com

nestjsとmulterを使用してファイルをアップロードする

Nestjsはエクスプレスアプリであるため、任意のライブラリを使用してnestを使用したアップロードを処理できます。また、Midlewaresを提供しているため、multerを使用することもできます。私の質問は、nestjsを使用してファイルのアップロードを処理するための最良の方法は何ですか?

3
Victor Ivens

問題について@Kamylから通知されたように https://github.com/nestjs/nest/issues/262v4.6.0は、共通のファイルインターセプターを使用してmulterを使用してnestjsにファイルをアップロードできるため。

import { ... , UseInterceptors, FileInterceptor, UploadedFile } from '@nestjs/common'

... 

@UseInterceptors(FileInterceptor('file'))
async upload( @UploadedFile() file) {
  console.log(file)
}

このようにして、変数filebufferになります


Multerオプションの使用

また、最初のパラメータとしてフィールド名が必要であり、次にMulterオプションを含む配列が必要です。

import { ... , UseInterceptors, FileInterceptor, UploadedFile } from '@nestjs/common'
import { diskStorage } from 'multer'
import { extname } from 'path'

...

@UseInterceptors(FileInterceptor('file', {
  storage: diskStorage({
    destination: './uploads'
    , filename: (req, file, cb) => {
      // Generating a 32 random chars long string
      const randomName = Array(32).fill(null).map(() => (Math.round(Math.random() * 16)).toString(16)).join('')
      //Calling the callback passing the random name generated with the original extension name
      cb(null, `${randomName}${extname(file.originalname)}`)
    }
  })
}))
async upload( @UploadedFile() file) {
  console.log(file)
}

このようにして、変数filefilenamedestination、およびpathを持ちます。

destinationdiskStorageパラメータも関数にすることができ、パラメータを使用して、コールバックをfilenameと同じにする必要があります。 diskStorageを渡すことにより、ファイルは指定されたファイル名で通知された宛先に自動的に保存されます。

@UploadedFilesおよびFilesInterceptor(複数形)を使用して複数のファイルを処理することもできます。

10
Victor Ivens

よりクリーンな方法は、構成を別のファイルに抽出し、それをインターセプターメソッド内で呼び出すことです。

import { extname } from 'path';
import { existsSync, mkdirSync } from 'fs';
import { diskStorage } from 'multer';
import { v4 as uuid } from 'uuid';
import { HttpException, HttpStatus } from '@nestjs/common';

// Multer configuration
export const multerConfig = {
    dest: process.env.UPLOAD_LOCATION,
};

// Multer upload options
export const multerOptions = {
    // Enable file size limits
    limits: {
        fileSize: +process.env.MAX_FILE_SIZE,
    },
    // Check the mimetypes to allow for upload
    fileFilter: (req: any, file: any, cb: any) => {
        if (file.mimetype.match(/\/(jpg|jpeg|png|gif)$/)) {
            // Allow storage of file
            cb(null, true);
        } else {
            // Reject file
            cb(new HttpException(`Unsupported file type ${extname(file.originalname)}`, HttpStatus.BAD_REQUEST), false);
        }
    },
    // Storage properties
    storage: diskStorage({
        // Destination storage path details
        destination: (req: any, file: any, cb: any) => {
            const uploadPath = multerConfig.dest;
            // Create folder if doesn't exist
            if (!existsSync(uploadPath)) {
                mkdirSync(uploadPath);
            }
            cb(null, uploadPath);
        },
        // File modification details
        filename: (req: any, file: any, cb: any) => {
            // Calling the callback passing the random name generated with the original extension name
            cb(null, `${uuid()}${extname(file.originalname)}`);
        },
    }),
};

そしてそれをインターセプターの下でそのように呼びます

import { ... , UseInterceptors, FileInterceptor, UploadedFile } from '@nestjs/common'
import { diskStorage } from 'multer'
import { extname } from 'path'
import { multerOptions } from 'src/config/multer.config';
...

@Post('/action/upload')
@UseInterceptors(FileInterceptor('file', multerOptions))
async upload( @UploadedFile() file) {
  console.log(file)
}
1
Sandeep K Nair