Nest.js 文件上传及自定义文件名保存

7,657 阅读2分钟

本人在学习使用 nest.js 的文件上传时发现保存的文件没有扩展名,差了很多资料,大多都过时了,结合那些资料,先给出我自己的解决代码:

新建 file.module.ts 文件,作为文件上传模块,代码如下:

import { Module } from '@nestjs/common';
import { FileController } from './file.controller';
import { FileService } from './file.service';
import { MulterModule } from '@nestjs/platform-express';
import dayjs = require('dayjs');
import { diskStorage } from 'multer';
import * as nuid from 'nuid';
@Module({
  imports: [
    MulterModule.register({
      storage: diskStorage({
        // 配置文件上传后的文件夹路径
        destination: `./public/uploads/${dayjs().format('YYYY-MM-DD')}`,
        filename: (req, file, cb) => {
          // 在此处自定义保存后的文件名称
          const filename = `${nuid.next()}.${file.mimetype.split('/')[1]}`;
          return cb(null, filename);
        },
      }),
    }),
  ],
  controllers: [
    FileController,
  ],
  providers: [FileService],
})
export class FileModule { }

新建 file.controller.ts 文件上传请求在此处理,代码如下:

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

@Controller('file')
export class FileController {
  @Post('upload')
  @UseInterceptors(FileInterceptor('file'))
  UploadedFile(@UploadedFile() file) {
    // 这里的 file 已经是保存后的文件信息了,在此处做数据库处理,或者直接返回保存后的文件信息
    return file;
  }
}

自定义原理:nest.js 文件上传基于 expressmulter,所以我们可以直接在文件上传引擎配置里面做处理就行了。

文件上传了就需要能后直接访问,这里就需要在项目入口文件 main.ts 里面做处理了,代码如下:

// 封装错误返回
import { HttpExceptionFilter } from './common/filter/http-exception.filter';
// dto 数据验证错误处理
import { ValidationPipe } from './common/pipe/validation.pipe';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
// 封装正确响应请求的返回
import { TransformInterceptor } from './common/interceptor/transform.interceptor';

import * as express from 'express';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // 配置 public 文件夹为静态目录,以达到可直接访问下面文件的目的
  const rootDir = join(__dirname, '..');
  app.use('/public', express.static(join(rootDir, 'public')));
  
  app.useGlobalPipes(new ValidationPipe());
  app.useGlobalFilters(new HttpExceptionFilter());
  app.useGlobalInterceptors(new TransformInterceptor());
  await app.listen(3000);
}
bootstrap();

这个原理其实还是用的 express 里面的东西,至于访问静态目录文件的大小、类型限制,可以参考 express 相关的地方,我水平有限,就不说了(ps:主要是自己还没弄懂,暂时会用一点点罢了,勿喷)。