Skip to content

中间件

中间件的作用

中间件的作用无非就是说在 Egg 的外层在包一层来判断某些事情是否符合要求,也就是在洋葱圈模型外面再进行包一层。

中间件的执行

在进入路由之前执行,可以用作全局验证或者报错处理等

中间件的使用

egg 约定一个中间件是一个放置在 app/middleware 目录下的单独文件,它需要导出一个普通的函数,该函数接受两个参数:

  • options: 中间件的配置项,框架会将 app.config[${middlewareName}] 传递进来。

  • app: 当前应用 Application 的实例。

  • 中间件分成全局使用和单个路由使用两种方式,下面分别进行介绍。

全局

  • 创建中间件

app/middleware下面新建一个 error.js 文件(随意起名)

js
module.exports = () => {
  return async function errorHandler(ctx, next) {
    const method = ctx.request.method;
    // 当请求方法为OPTIONS,通常为axios做验证请求,直接响应httpStatus204 no content即可
    if (method === "OPTIONS") {
      ctx.status = 204;
      return;
    }
    try {
      // 在这里捕获程序中的异常
      await next();
      // 404 页面就自己定义
      if (ctx.status === 404 && !ctx.body) {
        console.log(ctx);
        if (ctx.request.header["content-type"]) {
          ctx.body = { code: 404, msg: "接口不存在", data: "" };
        } else {
          // 跳转到404页面
          ctx.redirect("/");
        }
      }
    } catch (err) {
      // ... 其他异常处理,例如egg参数校验异常,可以在这里处理 // 最后其他异常统一处理
      ctx.status = 500;
      ctx.body = {
        code: 500,
        msg: err.message || "服务器异常",
        data: err.stack,
      };
    }
  };
};
  • 全局使用中间件

config.default.js中配置

js
module.exports = {
  // ...
  middleware: ["error"],
};

单个路由使用

  • 创建中间件

app/middleware下面新建一个 counter.js 文件(随意起名)

bash

module.exports = () => {
  return async (ctx, next) => {
    // 在中间件中执行一些操作
    console.log("counter middleware");
    if (ctx.session.counter) {
      ctx.session.counter++;
    } else {
      ctx.session.counter = 1;
    }
    // 继续处理下一个中间件
    await next();
  };
};
  • 单个路由使用中间件

app/router.js中配置

js
module.exports = (app) => {
  const { router, controller } = app;
  const counter = app.middleware.counter();
  // router
  const middleRouter = router.namespace("/getmiddleware");
  middleRouter.get(
    "/test",
    counter,
    controller.getmiddleware.getmiddleware.index
  );
};