【NestJS】中间件

中间件是在路由处理程序之前调用的函数,所以在中间件函数中可以访问请求和响应。

中间件函数需要执行 next() 将控制传递给下一个中间件函数,否则请求会被挂起。

可以使用 nest g mi XXX 创建中间件。



局部中间件

  1. nest g res user
  2. nest g mi ajax、编写中间件代码
import { Injectable, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';

@Injectable()
export class AjaxMiddleware implements NestMiddleware {
    use(req: Request, res: Response, next: NextFunction) {
        console.log('经过中间件');
        next();
    }
}
  1. 注册中间件
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { AjaxMiddleware } from 'src/ajax/ajax.middleware';

@Module({
    controllers: [UserController],
    providers: [UserService],
})
export class UserModule implements NestModule {
    /* 注册中间件;  可以 implements NestModule 获取代码提示 */
    configure(consumer: MiddlewareConsumer) {
        consumer.apply(AjaxMiddleware).forRoutes('user'); // 指定要拦截的路由
    }
}

现在所有访问 /user/* 的请求否会被中间件拦截

在这里插入图片描述


除了使用 forRoutes('user') 指定路由,还能给 forRoutes() 传入配置对象作为参数

import {
    MiddlewareConsumer,
    Module,
    NestModule,
    RequestMethod,
} from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { AjaxMiddleware } from 'src/ajax/ajax.middleware';

@Module({
    controllers: [UserController],
    providers: [UserService],
})
export class UserModule implements NestModule {
    configure(consumer: MiddlewareConsumer) {
        consumer.apply(AjaxMiddleware).forRoutes({
            path: 'user', // 指定拦截的路由
            method: RequestMethod.GET, // 仅拦截 GET 请求
        });
    }
}

此外,还能直接把 controller 传入 forRoutes() 作为参数,表示拦截该 controller 里面的所有请求

import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { AjaxMiddleware } from 'src/ajax/ajax.middleware';

@Module({
    controllers: [UserController],
    providers: [UserService],
})
export class UserModule implements NestModule {
    configure(consumer: MiddlewareConsumer) {
        // 拦截 UserController 里面的所有请求
        consumer.apply(AjaxMiddleware).forRoutes(UserController);
    }
}

若要指定多个路由应用中间件,可以给 forRoutes() 传入多个参数。

若要应用多个中间件,可以给 apply() 传入多个参数。



exclude

有时我们想从中间件中排除某些路由,可以使用 exclude()

consumer
    .apply(AjaxMiddleware)
    .exclude(
        { path: 'cats', method: RequestMethod.GET },
        { path: 'cats', method: RequestMethod.POST },
        'cats/(.*)',
    )
    .forRoutes('user');

若要排除多个路由,可以给 exclude() 传入多个参数。



函数式中间件

可以发现中间件的编写非常简单,就是一个类,类里面只有一个 use 函数。所以,我们也可以直接把中间件编写成一个函数:

import { NextFunction, Request, Response } from 'express';

export function ajaxMiddleware(
    req: Request,
    res: Response,
    next: NextFunction,
) {
    console.log('经过中间件');
    next();
}

然后就可以在别的 module 导入 ajax 并使用啦

consumer.apply(ajaxMiddleware).forRoutes('user');



全局中间件

只能使用函数式中间件作全局中间件

全局中间件的优先级比局部中间件高,会先执行

import { NextFunction, Request, Response } from 'express';

const whiteList = ['/user']; // 白名单

export function ajaxMiddleware(
    req: Request,
    res: Response,
    next: NextFunction,
) {
    console.log(req.originalUrl);
    if (whiteList.includes(req.originalUrl)) {
        next();
    } else {
        res.send('小黑子露出鸡脚了吧');
    }
}
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ajaxMiddleware } from 'src/ajax/ajax.middleware'; // 导入函数式中间件

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    app.use(ajaxMiddleware); // 使用中间件
    await app.listen(3000);
}
bootstrap();



第三方中间件

demo:使用 cors 处理跨域

  1. npm i cors (NestJS 内置了)
  2. 下载 Ts 类型支持:npm i @types/cors -D
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as cors from 'cors'; // 导入 cors

async function bootstrap() {
    const app = await NestFactory.create(AppModule);

    app.use(cors()); // 注册中间件

    await app.listen(3000);
}
bootstrap();



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JS.Huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值