跳至主要內容

文件上传

刘春龙原创...大约 3 分钟NodejsNestjs教程文档

为了处理文件上传,Nest 为 Express 提供了一个基于 multer 中间件包的内置模块。 Multer 处理以 multipart/form-data 格式发布的数据,该格式主要用于通过 HTTP POST 请求上传文件。 该模块是完全可配置的,你可以根据你的应用要求调整其行为。

警告

Multer 无法处理不支持的多部分格式 (multipart/form-data) 的数据。 另请注意,此包与 FastifyAdapter 不兼容。

为了更好的类型安全,让我们安装 Multer typings 包:

npm i -D @types/multer

单文件上传

要上传单个文件,只需将 FileInterceptor() 拦截器绑定到路由处理程序并使用 @UploadedFile() 装饰器从 request 中提取 file。

import { Controller, FileTypeValidator, Get, MaxFileSizeValidator, ParseFilePipe, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { UserService } from './user.service';
import { FileInterceptor } from '@nestjs/platform-express';
import { createWriteStream } from 'fs';

@Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) { }
  @Post("uploadOne")
  @UseInterceptors(FileInterceptor('file'))
  uploadOne(@UploadedFile() file: any) {
    const fileName = file.originalname
    const writeStream = createWriteStream(`src/public/upload/${fileName}`)
    writeStream.write(file.buffer)
  }
}

现在,你可以上传任意类型的文件,并且大小不受限制

验证

通常,验证传入的文件元数据很有用,例如文件大小或文件 mime 类型。 为此,你可以创建自己的 管道 并将其绑定到使用 UploadedFile 装饰器注释的参数。 下面的示例演示了如何实现基本的文件大小验证器管道:

Nest 提供了一个内置的管道来处理常见的用例并促进/标准化新的添加。 该管道称为 ParseFilePipe,你可以按如下方式使用它:

import { Controller, FileTypeValidator, Get, MaxFileSizeValidator, ParseFilePipe, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { UserService } from './user.service';
import { FileInterceptor } from '@nestjs/platform-express';
import { createWriteStream } from 'fs';

@Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) { }
  @Post("uploadOne")
  @UseInterceptors(FileInterceptor('file'))
  uploadOne(@UploadedFile(new ParseFilePipe({
    validators: [
      new MaxFileSizeValidator({ maxSize: 1000 }),
      new FileTypeValidator({ fileType: 'image' }),
    ]
  })) file: any) {
    const fileName = file.originalname
    const writeStream = createWriteStream(`src/public/upload/${fileName}`)
    writeStream.write(file.buffer)
  }
}

通过以上限制,你只能上传图片类型的文件,并且大小不能超过1000

上传文件名乱码问题解决

假如你上传的文件名称是中文命名,很大程度上后台接收的file.originalname是乱码的,此时你可以使用iconv-lite库进行解决乱码

npm i --save  iconv-lite

使用

const iconv = require('iconv-lite');
const fileName = iconv.decode(Buffer.from(file.originalname, 'binary'), 'utf-8')

多文件上传

要上传多个文件(所有文件都具有不同的字段名称键),请使用 FileFieldsInterceptor() 装饰器。 这个装饰器有两个参数:

  • uploadedFields: 一个对象数组,其中每个对象指定一个必需的 name 属性,其中一个字符串值指定一个字段名称,如上所述,以及一个可选的 maxCount 属性,如上所述
  • options: 可选的 MulterOptions 对象,如上所述

使用 FileFieldsInterceptor() 时,使用 @UploadedFiles() 装饰器从 request 中提取文件。

import { Controller, Post, UploadedFiles, UseInterceptors } from '@nestjs/common';
import { UserService } from './user.service';
import { FileFieldsInterceptor } from '@nestjs/platform-express';
import { createWriteStream } from 'fs';

@Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) { }
  @Post("uploadMore")
  @UseInterceptors(FileFieldsInterceptor([
    { name: 'file', maxCount: 9 },
    { name: 'image', maxCount: 1 },
    { name: 'video', maxCount: 9 },
    { name: 'audio', maxCount: 9 },
  ]))
  uploadOne(@UploadedFiles() file: any) {
    console.log(file);
    //注意把不同文件放进不同的文件夹
  }
}
上次编辑于:
贡献者: 刘春龙
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.7