Skip to content
本页目录

在 nest 中上传文件

前言

上传文件对平常业务中来说是一个不可避免的需求,本文将会介绍如何在 nest 中实现文件上传。

上传文件

在 nest 中上传文件一般使用 multer 中间件,multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。首先我们需要安装 multer 中间件:

bash
npm install --save @nestjs/platform-express multer

npm install -D @types/multer

然后在 nest 控制器中定义一个上传文件的接口:

typescript
import { Controller, Post, UseInterceptors, UploadedFile } from '@nestjs/common'
import { FileInterceptor } from '@nestjs/platform-express'

@Controller('upload')
export class UploadController {
  @Post('upload')
  @UseInterceptors(
    FileInterceptor('file', {
      dest: 'uploads',
    }),
  )
  uploadFile(@UploadedFile() file: Express.Multer.File, @Body() body) {
    console.log('body', body)
    console.log('file', file)
  }
}

上面只是一个单文件上传,如果是多个文件上传该怎么做呢?看下后端接口代码该如何编写

typescript
import { Controller, Post, UseInterceptors, UploadedFiles } from '@nestjs/common'
import { FilesInterceptor } from '@nestjs/platform-express'

@Controller('upload')
export class UploadController {
  @Post('upload')
  @UseInterceptors(
    FilesInterceptor('files', 3, {
      dest: 'uploads',
    }),
  )
  uploadFile(@UploadedFiles() files: Express.Multer.File[], @Body() body) {
    console.log('body', body)
    console.log('files', files)
  }
}

如果有多个字段来接收多个文件,那么我们可以这样写:

typescript
import { Controller, Post, UseInterceptors, UploadedFiles } from '@nestjs/common'
import { FilesInterceptor } from '@nestjs/platform-express'

@Controller('upload')
export class UploadController {
  @Post('upload')
  @UseInterceptors(
    FilesInterceptor(
      [
        { name: 'a', maxCount: 2 },
        { name: 'b', maxCount: 3 },
      ],
      {
        dest: 'uploads',
      },
    ),
  )
  uploadFile(
    @UploadedFiles() files: { a?: Express.Multer.File[]; b?: Express.Multer.File[] },
    @Body() body,
  ) {
    console.log('body', body)
    console.log('files', files)
  }
}

当不知道文件字段名的时候,我们可以使用 AnyFilesInterceptor 来接收所有的文件:

typescript
import { Controller, Post, UseInterceptors, UploadedFiles } from '@nestjs/common'
import { AnyFilesInterceptor } from '@nestjs/platform-express'

@Controller('upload')
export class UploadController {
  @Post('upload')
  @UseInterceptors(
    AnyFilesInterceptor({
      dest: 'uploads',
    }),
  )
  uploadFile(@UploadedFiles() files: Express.Multer.File[], @Body() body) {
    console.log('body', body)
    console.log('files', files)
  }
}

但是这样上传到文件夹下的文件是一个随机的文件名,如果我们想要自定义文件名,可以这样写:

typescript
import { Controller, Post, UseInterceptors, UploadedFiles } from '@nestjs/common'
import { AnyFilesInterceptor } from '@nestjs/platform-express'
import { diskStorage } from 'multer'

@Controller('upload')
export class UploadController {
  @Post('upload')
  @UseInterceptors(
    AnyFilesInterceptor({
      storage: diskStorage({
        destination: 'uploads',
        filename: (req, file, cb) => {
          const randomName = Array(32)
            .fill(null)
            .map(() => Math.round(Math.random() * 16).toString(16))
            .join('')
          return cb(null, `${randomName}${extname(file.originalname)}`)
        },
      }),
    }),
  )
  uploadFile(@UploadedFiles() files: Express.Multer.File[], @Body() body) {
    console.log('body', body)
    console.log('files', files)
  }
}

上传的文件也可以对其做大小和文件名的校验

typescript
import { Controller, Post, UseInterceptors, UploadedFiles } from '@nestjs/common'
import { AnyFilesInterceptor } from '@nestjs/platform-express'

@Controller('upload')
export class UploadController {
  @Post('upload')
  @UseInterceptors(
    FileInterceptor('file', {
      dest: 'uploads',
    }),
  )
  uploadFile(
    @UploadedFile(
      new ParseFilePipe({
        validators: [
          new MaxFileSizeValidator({ maxSize: 1000 }),
          new FileTypeValidator({ fileType: 'image/jpeg' }),
        ],
      }),
    )
    file: Express.Multer.File,
    @Body() body,
  ) {
    console.log('body', body)
    console.log('file', file)
  }
}

小结

本文介绍了如何在 nest 中上传文件,主要是使用 multer 中间件,在接口方面使用@UploadedFile()和@UploadedFiles()来接收文件,同时也介绍了如何对上传的文件做校验。

如有转载或 CV 的请标注本站原文地址