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

news2025/1/21 8:21:47

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;

实现效果

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

  • 登录账号或密码错误

在这里插入图片描述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2279732.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

我的创作纪念日——我与CSDN一起走过的365天

目录 一、机缘:旅程的开始 二、收获:沿路的花朵 三、日常:不断前行中 四、成就:一点小确幸 五、憧憬:梦中的重点 一、机缘:旅程的开始 最开始开始写博客是在今年一二月份的时候,也就是上一…

DenseNet-密集连接卷积网络

DenseNet(Densely Connected Convolutional Network)是近年来图像识别领域中一种创新且高效的深度卷积神经网络架构。它通过引入密集连接的设计,极大地提高了特征传递效率,减缓了梯度消失问题,促进了特征重用&#xff…

人形机器人将制造iPhone!

前言 优必选机器人和富士康通过一项突破性的合作伙伴关系,正在将先进的人形机器人(如Walker S1及其升级版Walker S2)整合到制造流程中,以改变iPhone的生产方式。这一合作旨在通过提升机器人能力、优化工作流程以及实现更智能的自动…

数据结构(链表 哈希表)

在Python中,链表和哈希表都是常见的数据结构,可以用来存储和处理数据。 链表是一种线性数据结构,由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。链表可以用来实现栈、队列以及其他数据结构。Python中可…

[苍穹外卖] 1-项目介绍及环境搭建

项目介绍 定位:专门为餐饮企业(餐厅、饭店)定制的一款软件产品 功能架构: 管理端 - 外卖商家使用 用户端 - 点餐用户使用 技术栈: 开发环境的搭建 整体结构: 前端环境 前端工程基于 nginx 运行 - Ngi…

vmware虚拟机配置ubuntu 18.04(20.04)静态IP地址

VMware版本 :VMware Workstation 17 Pro ubuntu版本:ubuntu-18.04.4-desktop-amd64 主机环境 win11 1. 修改 VMware虚拟网络编辑器 打开vmware,点击顶部的“编辑"菜单,打开 ”虚拟化网络编辑器“ 。 选择更改设置&#…

AUTOSAR OS模块详解(三) Alarm

AUTOSAR OS模块详解(三) Alarm 本文主要介绍AUTOSAR OS的Alarm,并对基于英飞凌Aurix TC3XX系列芯片的Vector Microsar代码和配置进行部分讲解。 文章目录 AUTOSAR OS模块详解(三) Alarm1 简介2 功能介绍2.1 触发原理2.2 工作类型2.3 Alarm启动方式2.4 Alarm配置2.5…

「免填邀请码」赋能各类APP,提升转化率与用户体验

在当前移动互联网的高速发展下,用户获取和留存已成为各类APP成功的关键。传统的注册流程虽然能够有效识别用户来源并进行用户管理,但随着市场竞争的激烈,复杂的注册和绑定步骤往往会成为用户流失的瓶颈。免填邀请码技术,结合自研的…

Linux:expect spawn简介与用法

一、背景 大家在使用linux系统的很多时候,都用linux指令来实现一些操作,执行特定的job,有时一些场景中需要执行交互指令来完成任务,比如ssh登录这个命令大家一定很熟悉: ssh-keygen -t rsa # 以及 ssh-copy-id -i /hom…

Express的接口

目录 接口的跨域问题域问题 request接口代码 const express require(express) const app express() //在路由之前,配置cors中间件,解决接口跨域问题 const cors require(cors) app.use(cors())const router require(./apiRouter)app.use(/api,rout…

【PCIe 总线及设备入门学习专栏 6.2 -- PCIe VDM (Vendor Defined Messages)】

文章目录 OverviewPCIe VDM (Vendor Defined Messages) 概述PCIe VDM Header 的各个字段及作用VDM 的工作方式例子:一个简化的 VDM 示例注意事项Overview 本文将详细介绍 PCIe VDM 及 PCIe VDM Header 各个域的作用。 PCIe VDM (Vendor Defined Messages) 概述 在 PCIe 协议…

微服务学习:基础理论

一、微服务和应用现代化 1、时代的浪潮,企业的机遇和挑战 在互联网化数字化智能化全球化的当今社会,IT行业也面临新的挑战: 【快】业务需求如“滔滔江水连绵不绝”,企业需要更快的交付【变】林子大了,百色用户&…

实战演示:利用ChatGPT高效撰写论文

在当今学术界,撰写论文是一项必不可少的技能。然而,许多研究人员和学生在写作过程中常常感到困惑和压力。幸运的是,人工智能的快速发展为我们提供了新的工具,其中ChatGPT便是一个优秀的选择。本文将通过易创AI创作平台&#xff0c…

【PCIe 总线及设备入门学习专栏 6 -- PCIe Inbound and Outbound】

文章目录 PCIe Outbound 和 Inbound 概念详解Outbound 与 Inbound 的基础定义基于角色的详细分析关于“上游”和“下游”方向应用举例小结PCIe Outbound 和 Inbound 概念详解 PCIe(Peripheral Component Interconnect Express)是一种高速串行通信协议,用于连接主机与外部设…

24年总结 -- 共赴心中所向往的未来

一、前言 我又回来了,前阵子忙着期末考试的东西,也是快半个月没更新了,刚好前几天报名了博客之星的评选,也很幸运的入围了,也借此机会来回顾一下关于2024年的个人成长、创作经历等。 二、个人 本人是一个双非学校的软…

嵌入式产品级-超小尺寸热成像相机(从0到1 硬件-软件-外壳)

Thermal_Imaging_Camera This is a small thermal imaging camera that includes everything from hardware and software. 小尺寸热成像相机-Pico-LVGL-RTOS 基于RP2040 Pico主控与RTOS,榨干双核性能实现LVGL和成图任务并行。ST7789驱动240280屏,CST8…

网络协议入门:OSI模型与TCP/IP栈

在网络通信的世界中,数据从一台设备传输到另一台设备,需要遵循一系列规则,这些规则统称为网络协议。OSI模型和TCP/IP协议栈作为网络通信的基石,帮助我们理解数据传输的全流程。这篇文章将深入解析它们的结构、功能和实际应用&…

HackMyVM-Klim靶机的测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、Getshell 3、提权 CVE-2008-0166 四、结论 一、测试环境 1、系统环境 渗透机:kali2021.1(192.168.159.127) 靶 机:debian(192.168.159.27) 注意事…

Mysql InnoDB B+Tree是什么?

“mysql中常用的数据库搜索引擎InnoDB,其索引通过BTree的方式进行构建。” 实在想不起来BTree是怎么一回事了。以点带线,将涉及到的数据结构一起复习一下。 文章目录 数据结构定义红黑树定义使命 BTree定义使命 BTree定义 InnoDB BTree 旋转与调整二叉排序树插入删…

docker 使用远程镜像启动一个容器

使用前提: 首先你得安装docker,其次你得拥有一个远程镜像 docker run --name io_11281009 --rm -it -p 2233:22 -v .:/root/py -e ed25519_rootAAAAC3NzaC1lZDI1********Oy7zR7l7aUniR2rul ghcr.lizzie.fun/fj0r/io srv对上述命令解释: 1.docker run:…