【JavaScript教程】nestJS系列–图片上传

零 JavaScript教程评论86字数 3099阅读10分19秒阅读模式

【JavaScript教程】nestJS系列--图片上传

前言

文件上传是每个项目都会用到的功能,NestJS在实现文件上传时,有TypeScript的强类型优势,确保代码安全稳定;语法十分的简洁,装饰器API如@UploadedFile()简化上传逻辑;支持自定义中间件增强功能,如验证和转换;其性能出色,尤其适合高并发场景;并且,NestJS与云存储服务的友好集成,使文件管理更加便捷;丰富的插件生态系统提供了更多扩展可能,进一步优化了开发体验。这些特点使得NestJS成为实现高效、安全文件上传的理想选择。

简单的文件上传

创建nestjs的项目的步骤这里就不做介绍了可以看我的《??超简单!!nestJS+jwt实现登录》这篇文章。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15602.html

  • 执行指令:nest g res uploads --no-spec, 一直按回车键
  • 安装 Multer typings 包:npm i -D @types/multer, 这样就可以有类型支持了

在uploads/uplods.controller.ts中将代码修改如下文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15602.html

ts

复制代码
import {
  Controller,
  Post,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { UploadsService } from './uploads.service';
import { FileInterceptor } from '@nestjs/platform-express';

@Controller('uploads')
export class UploadsController {
  constructor(private readonly uploadsService: UploadsService) {}

  @Post()
  @UseInterceptors(FileInterceptor('file', { dest: 'uploads' }))
  upload(@UploadedFile() file: Express.Multer.File) {
    console.log(file.path);
    return 0;
  }
}

@UseInterceptors: 使用拦截器,里面传一个拦截器函数就行了
@@UseInterceptors: 文件拦截器第一个参数是字段名第二参数是一个对象,dest是文件存放的位置,这个文件夹会自动创建。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15602.html

我们在apifox里面测试一下:文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15602.html

image.png image.png文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15602.html

可见已经正确的将文件的路径打印出来了。至此简单的文件上传已经完成了。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15602.html

文件验证

只允许图片上传

实现

将代码修改如下:文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15602.html

ts

复制代码
import {
  BadRequestException,
  Controller,
  Post,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { UploadsService } from './uploads.service';
import { FileInterceptor } from '@nestjs/platform-express';
import * as path from 'path';

@Controller('uploads')
export class UploadsController {
  constructor(private readonly uploadsService: UploadsService) {}

  @Post()
  @UseInterceptors(
    FileInterceptor('file', {
      dest: 'uploads',
      fileFilter(request, file, cal) {
        const ext = path.extname(file.originalname);
        if (['.jpg', '.png', '.jpeg'].includes(ext)) {
          return cal(null, true);
        } else {
          return cal(new BadRequestException('文件格式错误'), false);
        }
      },
    }),
  )
  upload(@UploadedFile() file: Express.Multer.File) {
    console.log(file.path);
    return 0;
  }
}

image.png文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15602.html

以上代码中新增了一个fileFilter函数,里面的参数主要看filecalfile就是传来的文件cal就是一个回调函数,如果ext在定义的文件后缀的数组中的时候第一个参数是null第二个参数是true否则第一个参数是一个异常对象第二个参数是false。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15602.html

在apifox里面测试一下,这里我先上传一个压缩文件文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15602.html

image.png image.png 显然返回报错信息了

试一下图片就正常返回了

image.png

可见我们的文件类型校验生效了,但是在装饰器里面写这么一坨校验的代码实在是不够美观,而且复用性也不强,我们可以封装一个聚合装饰器。

代码改造

创建custom-dec/custom.decorator.ts,新增如下代码:

ts

复制代码
import { Controller, Post, UploadedFile } from '@nestjs/common';
import { UploadsService } from './uploads.service';
import { FileUpload } from 'src/custom-dec/custom.decorator';

@Controller('uploads')
export class UploadsController {
  constructor(private readonly uploadsService: UploadsService) {}

  @FileUpload(['.jpeg', '.png'])
  @Post()
  upload(@UploadedFile() file: Express.Multer.File) {
    console.log(file.path);
    return 0;
  }
}

这段代码看似很多其实就是之前UseInterceptors装饰器整个剪切过来直接当参数放在applyDecorators函数里面,然后在外面套一个FileUpload函数,这个函数名随意,参数是文件类型,返回了applyDecorators执行结果。

改造upload路由

ts

复制代码
import { Controller, Post, UploadedFile } from '@nestjs/common';
import { UploadsService } from './uploads.service';
import { FileUpload } from 'src/custom-dec/custom.decorator';

@Controller('uploads')
export class UploadsController {
  constructor(private readonly uploadsService: UploadsService) {}

  @FileUpload(['.jpeg', '.png'])
  @Post()
  upload(@UploadedFile() file: Express.Multer.File) {
    console.log(file.path);
    return 0;
  }
}

image.png

这里将之前的UseInterceptors装饰器改成了我们自定义的聚合装饰器,并且文件类型自定义穿进去。 在apifox里面测试一下,先用不是图片的文件:

image.png

上传一个图片:

image.png

可见改造之后的代码是没有问题的,并且理由部分的代码简洁了许多。

图片大小限制

很简单,就是增加一个属性,这里限制最大为10m

image.png 由于我没有比10m大的图片所以我把图片类型限制去掉,上传一个压缩包发现大小限制生效了,在apifox里测试一下: image.png

零
  • 转载请务必保留本文链接:https://www.0s52.com/bcjc/javascriptjc/15602.html
    本社区资源仅供用于学习和交流,请勿用于商业用途
    未经允许不得进行转载/复制/分享

发表评论