自学内容网 自学内容网

【KOA框架】koa框架基础入门

koa是express的一层封装,语法比express更加简洁。所以有必要了解下koa的相关开发方法。

代码实现

  • package.json
{
  "name": "koapp",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "dev": "npx nodemon src/app.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "jsonwebtoken": "^9.0.2",
    "koa": "^2.15.3",
    "koa-bodyparser": "^4.4.1",
    "koa-jwt": "^4.0.4",
    "koa-router": "^13.0.1"
  }
}
  • 入口文件app.js
const Koa = require("koa");
const logger = require("./mid/logger");
const hello = require("./mid/hello");
const userRouter = require("./router/user");
const publicRouter = require("./router/public");
const sysRouter = require("./router/sys");
const bodyParser = require("koa-bodyparser");
const handlerError = require("./mid/errorHandle");
const Result = require("./utils/result");

const jwt = require("koa-jwt");
const secret = "zhangsanfeng";

const app = new Koa();
app.use(handlerError);

// 中间件 自定义了 401 响应,将用户验证失败的相关信息返回给浏览器
app.use(function (ctx, next) {
  return next().catch((err) => {
    if (401 == err.status) {
      ctx.status = 401;
      ctx.body = Result.error(401, "无效的token");
    } else {
      throw err;
    }
  });
});

app.use(
  jwt({
    secret,
    // passthrough: true,
    // cookie: "token", // 从 cookie 中获取token
    debugger: true,
  }).unless({ path: [/^\/public/, /^\/sys\/login/] })
);

// 注册路由中间件
app.use(bodyParser());

app.use(userRouter.routes()).use(userRouter.allowedMethods());
app.use(publicRouter.routes()).use(publicRouter.allowedMethods());
app.use(sysRouter.routes()).use(sysRouter.allowedMethods());

// 全局异常处理;
app.on("error", (error, ctx) => {
  console.log("ssss", error.status);
});

app.listen(3000);
  • 错误中间件
const Result = require("../utils/result");

async function handlerError(ctx, next) {
  try {
    await next(); // 执行后代的代码
    if (!ctx.body) {
      // 没有资源
      ctx.status = 404;
      // ctx.body = "404";
    }
  } catch (error) {
    // 如果后面的代码报错 返回500
    ctx.status = error.status;
    if (error.status == 404) {
      ctx.body = Result.error("找不到资源");
    } else if (error.status == 500) {
      console.log("🚀 ~ app.on ~ error.status:", error.status);
      ctx.body = Result.error("服务器异常,请稍后再试");
    } else if (error.status === 401) {
      ctx.body = Result.error("未授权 " + error.message);
    } else {
      ctx.body = Result.error("未知错误");
    }
    // ctx.body = "500";
  }
}

module.exports = handlerError;
  • 日志中间件
async function logger(ctx, next) {
  console.log("logger before...");
  await next();
  const rt = await ctx.response.get("X-Response-Time");
  console.log(`${ctx.method} ${ctx.url} - ${rt}`);
  console.log(ctx.username, "from mid");
  console.log("logger after...");
}
module.exports = logger;
  • 路由

不需要拦截的路由

const Router = require("koa-router");
const router = new Router();

router.prefix("/public");

router.get("/", async (ctx) => {
  console.log("🚀 ~ router.get ~ ctx:", ctx.params);
  ctx.body = {
    id: ctx.params.id,
    name: "小明1111",
    age: 18,
    sex: "男",
  };
  // ctx.throw(401);
});

router.get("/:id", async (ctx) => {
  console.log("🚀 ~ router.get ~ ctx:", ctx.params);
  ctx.body = {
    id: ctx.params.id,
    name: "小明",
    age: 18,
    sex: "男",
  };
  // ctx.throw(401);
});

module.exports = router;
  • 登录获取token的路由
const Router = require("koa-router");
const router = new Router();
const jwt = require("koa-jwt");
const { sign } = require("jsonwebtoken");
const Result = require("../utils/result");
const secret = "zhangsanfeng";

router.prefix("/sys");

router.post("/login", async (ctx, next) => {
  const body = ctx.request.body;
  if (body.username !== "zhangsan" || body.pwd !== "123456") {
    ctx.body = Result.error("账号或密码错误");
    // ctx.throw(401, "账号或密码错误");
  } else {
    const token = sign({ abcsd: "aaaaaa" }, secret, { expiresIn: "1h" });
    ctx.body = Result.success({ token });
  }
});

router.get("/userInfo", async (ctx, next) => {
  ctx.body = {
    name: "zhangsanfeng",
    age: 20,
    sex: "男",
  };
});

router.get("/logout", async (ctx, next) => {
  ctx.body = Result.success("退出成功");
  ctx.cookies.set("token", "", { signed: false, maxAge: 0 });
});

module.exports = router;
  • 用户路由
const Router = require("koa-router");
const router = new Router();

router.prefix("/user/s");

router.get("/:id", async (ctx) => {
  console.log("🚀 ~ router.get ~ ctx:", ctx.params);
  ctx.body = {
    id: ctx.params.id,
    name: "小明2222",
    age: 18,
    sex: "男",
  };
  // ctx.throw(401);
});

router.get("/", async (ctx) => {
  console.log("🚀 ~ router.get ~ ctx:", ctx.query);
  ctx.body = {
    id: ctx.params.id,
    name: "小明3333",
    age: 18,
    sex: "男",
  };
});

router.post("/", async (ctx) => {
  console.log("🚀 ~ router.get ~ ctx:", ctx.request.body);
  ctx.body = {
    id: ctx.params.id,
    name: "小明4444",
    age: 18,
    sex: "男",
  };
});

module.exports = router;
  • 工具方法
class Result {
  constructor(message, code, data) {
    this.message = message;
    this.code = code;
    this.data = data;
  }

  static success() {
    return new Result("success", 0, null);
  }
  static success(data) {
    return new Result("success", 0, data);
  }
  static error(message) {
    return new Result(message, null, 1);
  }
}

module.exports = Result;

实现效果

  • 未登录获取列表信息
    在这里插入图片描述

  • 登录账号或密码错误

在这里插入图片描述

  • 登录成功
    在这里插入图片描述
  • 获取用户信息成功
    在这里插入图片描述

原文地址:https://blog.csdn.net/qq_27702739/article/details/145266580

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!