
在 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()来接收文件,同时也介绍了如何对上传的文件做校验。