当前位置:网站首页>Nestjs配置文件上传, 配置中间件以及管道的使用
Nestjs配置文件上传, 配置中间件以及管道的使用
2022-07-06 04:43:00 【Johnny丶me】
Nestjs中的文件上传
- 文档: https://docs.nestjs.com/techniques/file-upload
安装插件
- $
yarn add @types/multer
示例
1 ) 简单单个上传
前端代码
<form action="upload/add" method="post" enctype="multipart/form-data"> <input type="file" name="files" /> <br> <br> <input type="submit" value="提交"> </form>
后端代码
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<Express.Multer.File>) { console.log(files); }
- 需要注意的是,我们每次上传时,这些路径,图片处理什么的,需要封装一下
Nestjs 中间件
- 同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);
管道
- 关于管道:https://docs.nestjs.com/pipes
- 管道的概念是主要用于将输入数据转换为所需的输出数据
- 或者处理Get,Post提交的数据
创建管道
$
nest g pipe cart
或指定路径生成 $
nest g middleware common/pipe/cart.pipe
创建一个cart的管道
import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common'; @Injectable() export class CartPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { return value; } }
说明:管道是由@Injectable()装饰器装饰的一个类
需要实现 PipeTransform 这个接口,并且实现其内部的一个 transform 方法
这里有两个参数:value,metadata
其中, value是传递到管道里的数据, metadata是一种类型
在这里面可以修改传入的值以及验证传入值的合法性
使用管道
在控制器中使用管道
import { Controller, Get, Query, UsePipes} from '@nestjs/common'; //引入管道 import { CartPipe } from '../../pipe/cart.pipe'; @Controller('cart') export class NewsController { @Get() @UsePipes(new CartPipe()) index(@Query() info){ console.log(info); return 'Cart' } }
由上面的代码可知,先要引入管道,之后使用UsePipes将引入的管道实例作为参数作为当前路由的一项装饰器
这里的info就会被传入到管道里面,也就是管道里的value参数
之后,在管道里就可以针对当前的值进行修改,校验等操作
关于管道中的校验
在接收到数据前,需要对数据进行一些校验等操作,这时候就比较适合在管道中写相关程序
一般而言,我们会借助第三方的库来帮助我们完成校验,官方给我们提供了使用joi库相关的示例
https://github.com/hapijs/joi,https://joi.dev/api/?v=17.6.0
下面做一下演示
// 控制器文件中使用 import { Controller, Get, Query, UsePipes } from '@nestjs/common'; import { UserPipe } from '../../pipe/user.pipe'; import * as Joi from 'joi'; // 定义 json schema const userSchema = Joi.object().keys({ name: Joi.string().required(), age: Joi.number().integer().min(6).max(66).required(), }) @Controller('user') export class UserController { @Get() @UsePipes(new UserPipe(userSchema)) index(@Query() info) { console.log(info); return '用户中心'; } }
// 在管道文件中 import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common'; @Injectable() export class UserPipe implements PipeTransform { private schema; constructor(schema){ this.schema=schema // 实例化的时候,参数传入 } transform(value: any, metadata: ArgumentMetadata) { const { error } = this.schema.validate(value); // 进行校验 // 如果错误,则提示,或统一返回相同的实体数据结构, 比如给前端提示 if(error) { return { "success": false}; } return value; } }
上面是基础用法,当然一般而言,也可以添加相关message信息,用于给前端用户提示
更多用法,请参考上面文档
边栏推荐
- 饼干(考试版)
- [数学建模] 微分方程--捕鱼业的持续发展
- Project manager, can you draw prototypes? Does the project manager need to do product design?
- Sqlserver query results are not displayed in tabular form. How to modify them
- web工程导入了mysql驱动jar包却无法加载到驱动的问题
- English Vocabulary - life scene memory method
- Redis - redis in action - redis actual combat - actual combat Chapter 1 - SMS login function based on redis - redis + token shared session application - with code
- It is also a small summary in learning
- 行业专网对比公网,优势在哪儿?能满足什么特定要求?
- newton interpolation
猜你喜欢
Mysql database storage engine
View workflow
Guitar Pro 8.0最详细全面的更新内容及全部功能介绍
Yyds dry inventory automatic lighting system based on CC2530 (ZigBee)
Fuzzy -- basic application method of AFL
MPLS experiment
ISP学习(2)
Basic knowledge and examples of binary tree
How to estimate the population with samples? (mean, variance, standard deviation)
Bill Gates posted his 18-year-old resume and expected an annual salary of $12000 48 years ago
随机推荐
ue5 小知识点 开启lumen的设置
The IPO of mesk Electronics was terminated: Henan assets, which was once intended to raise 800 million yuan, was a shareholder
P2102 floor tile laying (DFS & greed)
Certbot failed to update certificate solution
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
729. My schedule I (set or dynamic open point segment tree)
8. Static file
P3500 [poi2010]tes intelligence test (two points & offline)
[Yu Yue education] reference materials of complex variable function and integral transformation of Northwestern Polytechnic University
Easyrecovery reliable and toll free data recovery computer software
P2022 interesting numbers (binary & digit DP)
acwing周赛58
Visio draws Tai Chi
二叉树基本知识和例题
SQL injection vulnerability (MSSQL injection)
麥斯克電子IPO被終止:曾擬募資8億 河南資產是股東
How to realize automatic playback of H5 video
On the solution of es8316's audio burst
ORM aggregate query and native database operation
Implementation of knowledge consolidation source code 1: epoll implementation of TCP server