Skip to content

中间件

中间件 个人感觉不如拦截器 和 异常捕获器好用

中间件是在路由处理器之前被调用的函数.中间件函数可以访问请求和响应对象.以及应用程序请求-响应周期中的下一个中间件函数

下一个中间件函数通常用一个名为 next 的变量表示

Nest 中的中间件默认等同于 Express 中的中间件

中间件

中间件 == 拦截器 + 异常过滤器

但是中间件只能全局和局部使用

  • 执行任何代码

  • 修改请求和响应对象

  • 结束请求-响应周期

  • 调用堆栈中的下一个中间件

  • 如果当前中间件没有结束请求-响应周期.它必须调用 next()方法将控制权传递给下一个中间件,否则请求将被挂起

全局中间件

新建中间件文件

名字是 global.middleware.ts

这里面实现了 验证和捕获异常中间件

ts
import { Injectable, NestMiddleware } from "@nestjs/common";
import { Request, Response } from "express";
@Injectable()
export class GlobalMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: () => void) {
    console.log("请求前");
    if (req.headers["authorization"]) {
      try {
        next();
      } catch (e) {
        res.send({
          code: 500,
          message: "服务器错误",
          data: null,
        });
        return;
      }
    } else {
      res.status(401).send({
        code: 401,
        message: "未授权3",
        data: null,
      });
    }
  }
}

挂载到全局

  • 要是多个 就在apply(,,,)以逗号分开
ts
import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common";
import { GlobalMiddleware } from "./global/middleware/global.middleware";
import { LoginModule } from "./Login/login.module";
@Module({
  imports: [LoginModule],
  controllers: [],
  providers: [],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(GlobalMiddleware).forRoutes("*"); // apply middleware to all routes
  }
}

挂载到各个模块下面的modules,就仅仅对各个模块使用

局部中间件

排除

  • exclude 排除路由 这样里面的都不执行这个中间件

exclude 通过path和method 路径和请求方式必须都一样才会排除

ts
// logins 模块
import {
  MiddlewareConsumer,
  Module,
  NestModule,
  RequestMethod,
} from "@nestjs/common";
import { LoginController } from "./controller/login.controller";
import { LoginService } from "./service/login.service";
import { LoginMiddleware } from "./middleware/login.middleware";
@Module({
  imports: [],
  controllers: [LoginController],
  providers: [LoginService],
  exports: [],
})
export class LoginModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoginMiddleware)
      .exclude({ path: "logins/test2", method: RequestMethod.GET })
      .forRoutes("logins");
  }
}

只在某个路由使用

路径和 请求方法必须完全匹配才行

ts
import {
  MiddlewareConsumer,
  Module,
  NestModule,
  RequestMethod,
} from "@nestjs/common";
import { LoginController } from "./controller/login.controller";
import { LoginService } from "./service/login.service";
import { LoginMiddleware } from "./middleware/login.middleware";
@Module({
  imports: [],
  controllers: [LoginController],
  providers: [LoginService],
  exports: [],
})
export class LoginModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoginMiddleware)
      .forRoutes({ path: "logins/test2", method: RequestMethod.GET });
  }
}

限定控制器

ts
import {
  MiddlewareConsumer,
  Module,
  NestModule,
  RequestMethod,
} from "@nestjs/common";
import { LoginController } from "./controller/login.controller";
import { LoginService } from "./service/login.service";
import { LoginMiddleware } from "./middleware/login.middleware";
@Module({
  imports: [],
  controllers: [LoginController],
  providers: [LoginService],
  exports: [],
})
export class LoginModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoginMiddleware).forRoutes(LoginController);
  }
}

跨域

两种方法

  • 命令

main.ts使用命令

ts
const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(3000);
  • 通过参数
ts
const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(3000);