- 文档: https://docs.nestjs.com/techniques/file-upload
安装插件
- $ yarn add @types/multer
示例
1 ) 简单单个上传
-
前端代码
-
后端代码
import { Controller, Get, Render, Post, Body, UseInterceptors, UploadedFile } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; import { createWriteStream } from 'fs'; import { join } from 'path'; @Controller('upload') export class UploadController { @Get() @Render('default/upload') index() { } @Post('add') @UseInterceptors(FileInterceptor('files')) doAdd(@Body() body, @UploadedFile() file) { console.log(body); console.log(file); //上传图片的信息 必须在form的属性里面配置enctype="multipart/form-data" const writeStream = createWriteStream(join(__dirname, '../../public/upload', `${Date.now()}-${file.originalname}`)) writeStream.write(file.buffer); return '上传图片成功'; } }
2 ) 多文件上传
- 如果field一样(用的name都是files),我们可选择使用 UploadedFiles 的方法来处理,并且通过 for … of 来遍历
- 如果不一样,则提供了,如下的配置
@Post('upload') @UseInterceptors(FileFieldsInterceptor([ { name: 'avatar', maxCount: 1 }, { name: 'background', maxCount: 1 }, ])) uploadFile(@UploadedFiles() files: { avatar?: Express.Multer.File[], background?: Express.Multer.File[] }) { console.log(files); } - 或者使用Any类型的拦截器AnyFilesInterceptor
@Post('upload') @UseInterceptors(AnyFilesInterceptor()) uploadFile(@UploadedFiles() files: Array) { console.log(files); } - 需要注意的是,我们每次上传时,这些路径,图片处理什么的,需要封装一下
- 同express一样,nestjs中间件也可以理解为在请求和响应之间的一个管道处理程序
- 可以是一个函数,也可以是一个@Injectable() 装饰器装饰的类
中间件作用
- 执行任何代码
- 对请求和响应对象进行更改
- 结束请求-响应周期
- 调用堆栈中的下一个中间件函数
- 如果当前的中间件函数没有结束请求-响应周期, 它必须调用 next() 将控制传递给下一个中间件函数
- 否则, 请求将被挂起
中间件的创建和使用
1 ) 创建
- $ nest g middleware http 这里http是中间件名
- 会生成src/http.middleware.ts文件,如下:
import { Injectable, NestMiddleware } from '@nestjs/common'; @Injectable() export class HttpMiddleware implements NestMiddleware { use(req: any, res: any, next: () => void) { next(); } } - 我们按照文档上,改造一下
import { Injectable, NestMiddleware } from '@nestjs/common'; import { Request, Response, NextFunction } from 'express'; @Injectable() export class HttpMiddleware implements NestMiddleware { use(req: Request, res: Response, next: NextFunction) { console.log('Request...'); next(); } }
2 ) 在app.module.ts中使用
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { HttpMiddleware } from './http.middleware';
import { CatsModule } from './cats/cats.module'; // 模块
@Module({
imports: [CatsModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(HttpMiddleware)
// .forRoutes('cats'); // 表示哪些路由可以使用这个中间件
// .forRoutes(someController); // 匹配所有的路由 // 或者传入指定控制器,但是不建议这样写
// .forRoutes({path: 'cats', method: RequestMethod.GET}); // 只匹配GET
// .forRoutes({path: 'cats', method: RequestMethod.ALL}); // 匹配所有方法
// .forRoutes({path: 'cats', method: RequestMethod.ALL}, {path: 'user', method: RequestMethod.ALL}); // 配置多个
.forRoutes('*'); // 匹配所有的路由
}
}
- 当然,我们最好把中间件放到一个通用的模块中,如下:./common/middleware/
import { LoggerMiddleware } from './common/middleware/logger.middleware'; - 其实可以在创建的时候指定目录 $ nest g middleware common/middleware/http.middleware
3 ) 配置多个中间件的示例
3.1 一种配置
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { HttpMiddleware } from './http.middleware';
import { UserMiddleware } from './user.middleware';
@Module({
imports: [],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(HttpMiddleware).forRoutes('*')
.apply(UserMiddleware).forRoutes('user')
}
}
3.2 另一种配置
// 这里只写关键代码
consumer
.apply(NewsMiddleware,UserMiddleware)
.forRoutes({ path: 'u*r', method: RequestMethod.ALL},{ path: 'news', method: RequestMethod.ALL}) // 这里不讲究顺序
4 ) 函数式中间件
// 只写关键代码
export function logger(req, res, next) {
console.log(`函数式中间件...`);
next();
};
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(HttpMiddleware, logger).forRoutes('*')
}
}
5 ) 全局中间件
-
在main.ts中使用,注意不能使用类中间件,只能使用函数中间件
//全局中间件只能引入函数式中间件 import { logger } from './middleware/logger.middleware'; app.use(logger);



