Nest 实现文件上传的功能
我正在参加「掘金·启航计划」
文件上传是 Web 应用程序中常见的功能之一。Nest.js 底层的 HTTP 框架是 Express,它拥有众多强大的中间件来实现各种功能。
本文将介绍如何在 Nest.js 中借助 multer
中间件来实现文件上传的功能。
multer 中间件
Multer 中间件由 Express 团队出品,专门用来处理文件上传,它与 Express 框架紧密集成,在 Nest.js 中基本上也是使用 multer 来完成文件上传的功能。
Multer 的用法非常简单,只需要简单的几行配置,就能实现文件上传的常见需求,比如限制文件类型,大小,同时支持多文件上传。
Multer 是通过解析请求的 multipart/form-data
数据,从中提取文件并将其保存到指定位置或存储系统中。它支持多种存储方式,例如本地磁盘、云存储服务等。
初始化项目
首先使用 Nest CLI 创建项目:
$ nest new nest-upload
然后进入到项目目录,安装下需要的依赖:
$ pnpm add multer
$ pnpm add -D @types/multer
@types/multer 是 multer 中间件模块的类型声明包,可以提供获更好的类型安全。
它提供了一个
Express.Multer.File
类型,表示上传的文件。
配置 Multer 中间件
从内置的 @nestjs/platform-express
导入 MulterModule
模块,它提供的 register
方法可接收一系列的选项,来完成 multer 中间件的配置。
// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MulterModule } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import * as path from 'path';
@Module({
imports: [
MulterModule.register({
storage: diskStorage({
// 指定文件存储目录
destination: path.join(__dirname, '../uploads'),
// 通过时间戳来重命名上传的文件名
filename: (_, file, callback) => {
const fileName = `${
new Date().getTime() + path.extname(file.originalname)
}`;
return callback(null, fileName);
},
}),
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
文件上传控制器
在 app.controller.ts 中,添加一个处理文件上传请求的控制器方法,使用 @Post
装饰器指定处理 POST 请求的方法,使用 @UseInterceptors
和 @FileInterceptor
装饰器来处理文件上传。FileInterceptor
使用名称为 'file'
的字段来接收上传的文件。
import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { AppService } from './app.service';
import { FileInterceptor } from '@nestjs/platform-express';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
async uploadFile(
@UploadedFile() file: Express.Multer.File,
): Promise<{ url: string }> {
const fileUrl = await this.appService.uploadFile(file);
return { url: fileUrl };
}
}
该控制器方法最终返回一个包含文件 Url 的对象,响应给客户端。客户端可以通过这个 URL 去访问文件资源。
创建文件上传的服务
在 app.service.ts 中创建一个服务来处理文件上传的逻辑。
import { Injectable } from '@nestjs/common';
import { MulterDiskUploadedFiles } from '@nestjs/platform-express';
import * as path from 'path';
@Injectable()
export class FileUploadService {
async uploadFile(file: Express.Multer.File): Promise<string> {
// 到这里其实文件已经上传到服务器本地了,需要有后续的存储需求,比如要上传到云存储服务中,可以在这里继续处理
// 返回文件URL
return `http://localhost/uploads/${file.filename}`;
}
}
测试接口
使用 ApiPost 等工具来测试一下接口,通过发送 POST 请求到 /upload
路由来测试文件上传功能。使用一个名为 'file'
的文件字段,来包含要上传的文件。
打开本地项目的根目录,确实有一个 uploads 目录,里面存放了刚刚上传的文件:
小结
本文简单介绍了如何在 Nest 中借助 multer 中间件来完成文件上传的功能,实现非常简单,multer 还支持多文件上传,自定义存储器等好用的功能,大家可以尝试一下。
转载自:https://juejin.cn/post/7234807896146935864