当前位置:网站首页>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信息,用于给前端用户提示
更多用法,请参考上面文档
边栏推荐
- Implementation of knowledge consolidation source code 2: TCP server receives and processes half packets and sticky packets
- [Yu Yue education] reference materials of complex variable function and integral transformation of Northwestern Polytechnic University
- Use sentinel to interface locally
- ISP learning (2)
- 【Try to Hack】john哈希破解工具
- [NOIP2008 提高组] 笨小猴
- The video in win10 computer system does not display thumbnails
- Chip debugging of es8316 of imx8mp
- ETCD数据库源码分析——etcdserver bootstrap初始化存储
- [数学建模] 微分方程--捕鱼业的持续发展
猜你喜欢

8. Static file

How do programmers teach their bosses to do things in one sentence? "I'm off duty first. You have to work harder."

Delete subsequence < daily question >

ISP学习(2)

Postman前置脚本-全局变量和环境变量

CADD course learning (8) -- virtual screening of Compound Library

Uva1592 Database
![[Zhao Yuqiang] deploy kubernetes cluster with binary package](/img/be/8710605c8da8d1553af974f0dc46bc.jpg)
[Zhao Yuqiang] deploy kubernetes cluster with binary package

11. Intranet penetration and automatic refresh

二叉树基本知识和例题
随机推荐
Meet diverse needs: jetmade creates three one-stop development packages to help efficient development
Complete list of common functions of turtle module
Implementation of knowledge consolidation source code 2: TCP server receives and processes half packets and sticky packets
Supreme Court, judgment standard of divorce cases
MPLS experiment
ISP learning (2)
SQL injection vulnerability (MSSQL injection)
内核判断i2c地址上是否挂载外设
Sqlserver query results are not displayed in tabular form. How to modify them
MIT CMS. 300 session 8 – immersion / immersion
Request (request object) and response (response object)
Microservice resource address
力扣(LeetCode)186. 翻转字符串里的单词 II(2022.07.05)
RTP GB28181 文件测试工具
比尔·盖茨晒18岁个人简历,48年前期望年薪1.2万美元
Programmers' position in the Internet industry | daily anecdotes
Easyrecovery reliable and toll free data recovery computer software
Can CDC pull the Oracle table in full
Redis —— Redis In Action —— Redis 实战—— 实战篇一 —— 基于 Redis 的短信登录功能 —— Redis + Token 的共享 session 应用— 有代码
Jd.com 2: how to prevent oversold in the deduction process of commodity inventory?