Koa学习

news2024/11/24 9:56:50

Koa 安装与配置

1. 初始化项目

在终端中执行以下命令:

# 创建项目文件夹
mkdir koa
cd koa

# 初始化并安装依赖
npm init -y
npm install koa
npm install nodemon --save-dev

2. 修改 package.json

package.json 文件中进行如下修改:

{
	"type": "module",
	"scripts": {
		"dev": "nodemon index.js",
		"test": "echo \"Error: no test specified\" && exit 1"
	}
}

3. 编写初始化代码

在终端中新建 index.js 文件:

# 测试代码文件
code index.js

index.js 中添加以下代码:

import Koa from 'koa';

const hostname = "127.0.0.1"; // 服务器监听的 IP 地址
const port = 8008; // 服务器监听的端口号

// 实例化一个 Koa 对象
const app = new Koa();

// 注册中间件
app.use(async ctx => {
    ctx.body = "Helloworld"; // 设置响应体的内容
});

// 启动 HTTP 服务器
app.listen(port, hostname, () => {
    console.log(`服务器已启动: http://${hostname}:${port}`);
});

4. 启动服务器

在终端中运行以下命令以启动服务器:

npm run dev

2. 中间件

import Koa from 'koa';

const hostname = "127.0.0.1"; // 服务器监听的 IP 地址
const port = 8008; // 服务器监听的端口号

// 实例化一个 Koa 对象
const app = new Koa();

// 演示中间件
app.use(async (ctx, next) => {
    console.log(111);
    await next();
    console.log(222);
});

// 注册中间件
app.use(async ctx => {
    ctx.body = "Helloworld"; // 设置响应体的内容
    console.log(333);
});

// 启动 HTTP 服务器
app.listen(port, hostname, () => {
    console.log(`服务器已启动: http://${hostname}:${port}`);
});

打印两遍是因为请求了图标,block即可

在这里插入图片描述


3. 安装和配置路由 - GET 请求

安装路由:

npm i @koa/router

测试代码:

import Koa from 'koa';
import Router from '@koa/router';

const hostname = "127.0.0.1"; // 服务器监听的 IP 地址
const port = 8008; // 服务器监听的端口号

// 实例化一个 Koa 对象
const app = new Koa();
const router = new Router(); // 实例化一个 Router 对象

router.get('/', async ctx => { // GET 请求
    ctx.body = "Helloworld";
});

router.get('/test', async ctx => { // GET 请求
    let id = ctx.query.id;
    let web = ctx.query.web;
    ctx.body = id + " : " + web;
});

router.get('/test2/id/:id/web/:web', async ctx => {
    let id = ctx.params.id;
    let web = ctx.params.web;
    ctx.body = id + " : " + web;
});

router.redirect('/test3', 'https://www.baidu.com');

app.use(router.routes());

// ************************
const userRouter = new Router({ prefix: '/user' });
userRouter.get('/add', async ctx => {
    ctx.body = "添加用户";
});
userRouter.get('/del', async ctx => {
    ctx.body = "删除用户";
});
app.use(userRouter.routes());

// 在所有路由之后添加 404 处理函数
app.use(async ctx => {
    if (!ctx.body) { // 若没有设置 ctx.body, 则说明没有匹配任何路由
        ctx.status = 404;
        ctx.body = '404 Not Found';
    }
});

// 启动 HTTP 服务器
app.listen(port, hostname, () => {
    console.log(`服务器已启动: http://${hostname}:${port}`);
});

4. POST 请求

安装 @koa/bodyparser

npm i @koa/bodyparser

测试代码:

import Koa from 'koa';
import Router from '@koa/router';
import BodyParser from '@koa/bodyparser';

const hostname = "127.0.0.1"; // 服务器监听的 IP 地址
const port = 8008; // 服务器监听的端口号

// 实例化一个 Koa 对象
const app = new Koa();
const router = new Router(); // 实例化一个 Router 对象

app.use(BodyParser()); // 使用 @koa/bodyparser 中间件来解析 POST 请求

// ------ POST 请求
// [application/x-www-form-urlencoded] http://127.0.0.1:8008/postUrl
router.post('/postUrl', async ctx => {
    let id = ctx.request.body.id;
    let web = ctx.request.body.web;
    ctx.body = id + " : " + web;
});

// [application/json] http://127.0.0.1:8008/postJson
router.post('/postJson', async ctx => {
    let id = ctx.request.body.id;
    let web = ctx.request.body.web;
    ctx.body = id + " : " + web;
});

app.use(router.routes()); // 将定义在 router 对象中的路由规则添加到 app 实例中

// 启动 HTTP 服务器
app.listen(port, hostname, () => {
    console.log(`服务器已启动: http://${hostname}:${port}`);
});

5. 错误处理

测试代码:

import Koa from 'koa';
import Router from '@koa/router';

const hostname = "127.0.0.1";
const port = 8008;

const app = new Koa();
const router = new Router();

router.get('/', async ctx => {
    throw new Error("测试");
});

/*
    将 '错误处理中间件' 放在 '路由处理中间件' 之前, 当一个请求到达时,
    会先经过 '错误处理中间件', 然后才会进入 '路由处理中间件',
    是为了确保可以捕获错误
*/
app.use(async (ctx, next) => { // 错误处理中间件
    try {
        await next();
    } catch (err) {
        console.log('err:', err);
        ctx.status = 500;
        ctx.body = 'err: ' + err.message;
    }
});

app.use(router.routes()); // 路由处理中间件

app.listen(port, hostname, () => {
    console.log(`服务器已启动: http://${hostname}:${port}`);
});

6. 跨域

测试代码:

import Koa from 'koa';
import Router from '@koa/router';
import Cors from '@koa/cors';

const hostname = "127.0.0.1";
const port = 8008;

const app = new Koa();
const router = new Router(); // 实例化一个 Router 对象

app.use(Cors()); // 允许跨域请求

router.get('/', async ctx => { // GET 请求
    ctx.body = "Helloworld";
});

app.use(router.routes()); // 将定义在 router 对象中的路由规则添加到 app 实例中

app.listen(port, hostname, () => {
    console.log(`服务器已启动: http://${hostname}:${port}`);
});

7. Koa 图片上传功能实现指南

1. 安装依赖

在终端中执行以下命令以安装 @koa/multer

npm install @koa/multer

注意事项

安装过程中可能会出现如下警告:

npm warn deprecated @babel/plugin-proposal-export-namespace-from@7.18.9:
This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained.
Please use @babel/plugin-transform-export-namespace-from instead.

2. 编写代码

index.js 中添加以下代码:

import Koa from 'koa';
import Router from '@koa/router';
import BodyParser from '@koa/bodyparser';
import Cors from '@koa/cors';
import Multer from '@koa/multer';
import path from 'path';

const hostname = "127.0.0.1";
const port = 8008;

const app = new Koa();
const router = new Router(); // 实例化一个 Router 对象

app.use(BodyParser()); // 使用 @koa/bodyparser 中间件解析 POST 请求
app.use(Cors()); // 允许跨域请求

// 配置磁盘存储引擎
const storage = Multer.diskStorage({
    destination: (request, file, callbackFunc) => { // 指定文件保存路径
        callbackFunc(null, './upload');
    },
    filename: (request, file, callbackFunc) => { // 设置文件名
        callbackFunc(null, Date.now() + path.extname(file.originalname));
    },
});

const multer = Multer({ // 实例化一个 Multer 对象
    storage, // 磁盘存储引擎
    limits: { // 限制条件
        fileSize: 2 * 1024 * 1024, // 限制文件大小为 2MB
    },
    fileFilter: (request, file, callbackFunc) => { // 文件过滤器
        const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png'];
        if (allowedTypes.includes(file.mimetype)) {
            callbackFunc(null, true);
        } else {
            callbackFunc(new Error('不支持的文件类型'), false);
        }
    }
});

// 上传接口
router.post('/upload', multer.single('file'), async ctx => {
    const file = ctx.request.file; // 获取上传的文件信息
    if (file) {
        console.log(file);
        ctx.body = "文件上传成功";
    }
});

// 错误处理中间件
app.use(async (ctx, next) => {
    try {
        await next();
    } catch (err) {
        ctx.status = 500;
        ctx.body = 'err: ' + err.message;
    }
});

app.use(router.routes()); // 路由处理中间件

// 启动服务器
app.listen(port, hostname, () => {
    console.log(`服务器已启动: http://${hostname}:${port}`);
});

3. 启动服务器

在终端中运行以下命令以启动服务器:

npm run dev

4. 上传文件

使用 POST 请求上传文件到 http://127.0.0.1:8008/upload,确保请求中包含名为 file 的文件字段。

在这里插入图片描述


8. Cookie

测试代码:

import Koa from 'koa';
import Router from '@koa/router';

const hostname = "127.0.0.1";
const port = 8008;

const app = new Koa();
const router = new Router(); // 实例化一个 Router 对象

// Cookie 可用于在浏览器中存储数据
router.get('/', async ctx => {
    // 赋值
    ctx.cookies.set("name", encodeURIComponent("hello")); // encodeURIComponent: URL 编码
    ctx.cookies.set("web", "baidu.com", {
        maxAge: 5 * 1000, // 30 秒 [maxAge: 有效期 单位: 毫秒]
        httpOnly: false // 允许浏览器通过 JS 访问和修改该 cookie
    });

    // 取值 - 在同一个请求内, 无法立即获取到刚刚设置的 cookie 的值
    let name = ctx.cookies.get("name");
    console.log("name:", decodeURIComponent(name)); // decodeURIComponent: URL 解码

    // 删除
    // ctx.cookies.set("name", "", { maxAge: 0 });

    ctx.body = "Helloworld";
});

app.use(router.routes()); // 将定义在 router 对象中的路由规则添加到 app 实例中

app.listen(port, hostname, () => {
    console.log(`服务器已启动: http://${hostname}:${port}`);
});

9. Session(存在客户端的 Cookie 中,一般别用)

安装 koa-session

npm i koa-session

测试代码:

import Koa from 'koa';
import Router from '@koa/router';
import Session from 'koa-session';

const hostname = "127.0.0.1";
const port = 8008;

const app = new Koa();
const router = new Router(); // 实例化一个 Router 对象

// koa-session 默认将 session 数据存储在客户端的 cookie 中
app.keys = ['session.dengruicode.com']; // 设置会话签名的密钥
const CONFIG = {
    key: 'DR', // 存储在 cookie 中的键名
    maxAge: 24 * 60 * 60 * 1000, // 24 小时 有效期 (单位: 毫秒)
    signed: true, // 是否启用会话签名, 用于防止 CSRF 攻击
    secure: false, // 是否仅通过 https 协议发送 cookie
};
app.use(Session(CONFIG, app));

router.get('/', async ctx => {
    // 赋值
    ctx.session.name = "邓瑞";
    ctx.session.url = "dengruicode.com";
    if (!ctx.session.user) {
        ctx.session.user = 100;
    } else {
        ctx.session.user++;
    }

    // 取值
    let name = ctx.session.name;
    console.log("name:", name);

    // 删除
    // ctx.session = null; // 清空
    // delete ctx.session.name; // 删除 session 中的 name 属性

    ctx.body = "用户:" + ctx.session.user;
});

app.use(router.routes()); // 将定义在 router 对象中的路由规则添加到 app 实例中

app.listen(port, hostname, () => {
    console.log(`服务器已启动: http://${hostname}:${port}`);
});

10. JWT

安装 jsonwebtoken

npm i jsonwebtoken

JWT 结构

JWT(JSON Web Token)是一种基于令牌的认证和授权机制,由三部分组成:Header(头部)、Payload(负载)、Signature(签名)。

Header(头部)

{
  "alg": "HS256", // algorithm 算法
  "typ": "JWT" // type 类型
}

Payload(负载)

{
  "sub": 1, // Subject 主题 (用户唯一 ID)
  "iss": "dengruicode.com", // Issuer 发行者
  "iat": 1719930255, // Issued At 发行时间
  "nbf": 1719930255, // Not Before 生效时间
  "exp": 1720016655, // Expiration Time 过期时间
  "aud": [ // Audience 观众字段为空, 表示没有观众限制, 可以被任何接收方处理
    ""
  ],
  "data": { // 自定义数据
    "name": "邓瑞",
    "gender": "男"
  }
}

Signature(签名)

HMACSHA256(
  base64UrlEncode(Header) + "." +
  base64UrlEncode(Payload),
  密钥
)

测试代码:

import Koa from 'koa';
import Router from '@koa/router';
import JWT from 'jsonwebtoken';

const hostname = "127.0.0.1";
const port = 8008;

const app = new Koa();
const router = new Router(); // 实例化一个 Router 对象

router.get('/', async ctx => {
    let key = 'koaTest'; // 密钥
    let token = generateToken(key); // 生成 token

    parseToken(token, key); // 解析 token

    ctx.body = token;
});

app.use(router.routes()); // 将定义在 router 对象中的路由规则添加到 app 实例中

// 生成 token
let generateToken = key => {
    let id = 1; // 用户唯一 ID
    let now = Math.floor(Date.now() / 1000); // 当前时间戳 单位: 秒
    let expire = 24 * 60 * 60;

    // 负载
    let payload = {
        sub: id, // Subject 主题 (用户唯一 ID)
        iss: 'dengruicode.com', // Issuer 发行者
        iat: now, // Issued At 发行时间
        nbf: now, // Not Before 生效时间
        exp: now + expire, // Expiration Time 过期时间
        aud: [''], // Audience 观众字段为空, 表示没有观众限制, 可以被任何接收方处理
        data: { // 自定义数据
            name: '邓瑞',
            gender: '男',
        }
    };

    // 使用负载(payload)、密钥(key)和指定的签名算法(HS256)生成 token
    let token = JWT.sign(payload, key, { algorithm: 'HS256' });
    return token;
};

// 解析 token
let parseToken = (token, key) => {
    let payload = JWT.verify(token, key, { algorithm: 'HS256' });
    console.log('解析后的 payload:', payload);
};

app.listen(port, hostname, () => {
    console.log(`服务器已启动: http://${hostname}:${port}`);
});

以上是 Koa 的基本使用指南和功能实现,包括中间件、路由、错误处理、跨域、文件上传、Cookie、Session 和 JWT 等功能。确保在实际开发中根据需求进行适当的修改和扩展。

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

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

相关文章

LeetCode讲解篇之1143. 最长公共子序列

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 这题我们可以采用动态规划求解&#xff0c;用一个二维数组记录text1的0 ~ i区间子串和text2的0 ~ j区间子串的最长公共子序列的长度&#xff0c;我们假设该二维数组是f 这个数组有一个特性&#xff0c;如果a <…

ssm服装店销售管理系统

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 摘 要 I Abstract II 第1章 绪论 1 1.1研究背景 1 1.2研究意义 1 1.3国内外研究现状 2 1.3.1国外研…

R语言中的plumber介绍

R语言中的plumber介绍 基本用法常用 API 方法1. GET 方法2. POST 方法3. 带路径参数的 GET 方法 使用 R 对数据进行操作处理 JSON 输入和输出运行 API 的其他选项其他功能 plumber 是个强大的 R 包&#xff0c;用于将 R 代码转换为 Web API&#xff0c;通过使用 plumber&#x…

启动hadoop后没有 NodeManager和 ResourceManager

跟着黑马网课学下去时发现我的hadoop启动后没有NodeManager和ResourceManager 找到日志的路径 我在/export/server/hadoop/etc/hadoop/hadoop-env.sh文件里配置了日志存放的路径 这里找到你的日志路径&#xff0c;每个人的习惯和看的教程不同&#xff0c;日志放的地方大概率也…

MATLAB中lsqminnorm函数用法

目录 语法 说明 示例 求解具有无限个解的线性系统 指定容差以减少含噪数据的影响 切换显示低秩矩阵警告 lsqminnorm函数的功能是线性方程的最小范数最小二乘解。 语法 X lsqminnorm(A,B) X lsqminnorm(A,B,tol) X lsqminnorm(___,rankWarn) 说明 X lsqminnorm(A,B…

【大语言模型-论文精读】用于医疗领域摘要任务的大型语言模型评估综述

【大语言模型-论文精读】用于医疗领域摘要任务的大型语言模型评估综述 论文信息&#xff1a; 用于医疗领域摘要任务的大型语言模型评估&#xff1a;一篇叙述性综述&#xff0c; 文章是由 Emma Croxford , Yanjun Gao 博士 , Nicholas Pellegrino , Karen K. Wong 等人近期合作…

【Arduino IDE安装】Arduino IDE的简介和安装详情

目录 &#x1f31e;1. Arduino IDE概述 &#x1f31e;2. Arduino IDE安装详情 &#x1f30d;2.1 获取安装包 &#x1f30d;2.2 安装详情 &#x1f30d;2.3 配置中文 &#x1f30d;2.4 其他配置 &#x1f31e;1. Arduino IDE概述 Arduino IDE&#xff08;Integrated Deve…

Spring Boot医院管理系统:提升患者体验

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

python pass的作用

class Phone: IMEI None # 序列号 producer “ITCAST” # 厂商 def call_by_4g(self):print("4g通话")class Phone2022(Phone): face_id “10001” # 面部识别ID def call_by_5g(self):print("2022年新功能&#xff1a;5g通话")class NFCReader: nfc_ty…

​​​​​​​如何使用Hugging Face上的FacePoke工具调整照片中人的头部位置

在照片处理中&#xff0c;调整人物的头部位置可以为你带来创意无限的效果。借助Hugging Face上的FacePoke工具&#xff0c;这一操作变得前所未有的简单和高效。以下是详细步骤&#xff0c;教你如何使用FacePoke来调整照片中人的头部位置。 第一步&#xff1a;访问FacePoke工具…

二、Python(项目创建、常见的设置、print函数)

一、项目创建 二、常见设置 1.字体大小 2.插件 3.主题设置 4.配置解释器 三、print函数 在 Python 中&#xff0c;print()函数是一个非常重要的用于输出内容的函数。 作用&#xff1a;print函数在控制台中输出(显示,打印)括号中的内容&#xff0c;可以用于验证代码的输出结果…

【Kubernetes】常见面试题汇总(五十八)

目录 127.创建 PV 失败&#xff1f; 128. pod 无法挂载 PVC&#xff1f; 特别说明&#xff1a; 题目 1-68 属于【Kubernetes】的常规概念题&#xff0c;即 “ 汇总&#xff08;一&#xff09;~&#xff08;二十二&#xff09;” 。 题目 69-113 属于【Kubernetes】…

SpringBoot开发——SpringSecurity安全框架17个业务场景案例(一)

文章目录 一、Spring Security 常用应用场景介绍二、Spring Security场景案例1、认证(Authentication)1.1. Spring Security 配置1.2 业务逻辑代码1.3 登录控制器1.4 登录页面 (login.html)2、授权(Authorization)2.1 Spring Security 配置2.2 业务逻辑代码2.3 控制器3、表…

如何判断静态代理IP地址是否被污染?

在网络使用中&#xff0c;静态IP代理是一种常见的工具&#xff0c;用于维持稳定的连接和保护个人隐私。然而&#xff0c;有时这些IP地址可能会被污染&#xff0c;导致用户遭受各种问题&#xff0c;如连接延迟、数据泄露等。因此&#xff0c;了解如何判断址是否被污染至关重要。…

EPC User Manual Introduction

Overview 您提供的链接是指向srsRAN 4G项目的官方文档&#xff0c;具体是关于srsEPC的介绍部分。以下是该页面的核心内容概要&#xff1a; ### 概述 srsEPC是一个轻量级的完整LTE核心网络&#xff08;EPC&#xff09;实现。srsEPC应用程序作为一个单一的二进制文件运行&#…

【高阶数据结构】二叉树进阶探秘:AVL树的平衡机制与实现详解

高阶数据结构相关知识点可以通过点击以下链接进行学习一起加油&#xff01;二叉搜索树 大家好&#xff0c;这里是店小二&#xff01;今天我们将深入探讨高阶数据结构中的AVL树。AVL树是一种自平衡的二叉搜索树&#xff0c;可以看作是对传统二叉搜索树的优化版本。如果你对数据结…

828华为云征文|华为云Flexus云服务器X实例部署 即时通讯IM聊天交友软件——高性能服务器实现120W并发连接

营运版的即时通讯IM聊天交友系统&#xff1a;特点可发红包&#xff0c;可添加多条链接到用户网站和应用&#xff0c;安卓苹果APPPC端H5四合一 后端开发语言&#xff1a;PHP&#xff0c; 前端开发语言&#xff1a;uniapp混合开发。 集安卓苹果APPPC端H5四合一APP源码&#xff0…

AI学习记录 - L2正则化详细解释(权重衰减)

大白话&#xff1a; 通过让反向传播的损失值变得比原来更大&#xff0c;并且加入的损失值和权重的大小有关&#xff0c;当出现权重的平方变大的时候&#xff0c;也就是权重往更加负或者更加正的方向走的时候&#xff0c;损失就越大&#xff0c;从而控制极大正或者极大负的情况…

在宝塔面板中部署 Express + MongoDB + Uniapp h5 项目(超详细!!!)

文章目录 一、打包 uniapp h5 项目(1) 打开 manifest.json 文件&#xff0c;修改相关配置(2) 开始项目打包 二、修改 express 相关配置(1) 添加打包后的前端资源文件(2) 修改 app.js 文件(3) 修改项目启动命令 三、使用宝塔面板部署项目(1) 宝塔面板安装(2) 项目环境搭建 四、添…

之前各种炸裂的Flux更新了Flux1.1 pro,效果会不会依然“炸裂”呢?

&#x1f420;更新内容 Black Forest Labs&#xff0c;也就是黑森林工作室在国庆期间更新了新的模型&#xff0c;Flux1.1 Pro&#xff0c;官方公告大家也可以参考&#xff1a; announcements. - Black Forest Labs 那么这次更新主要讲了什么呢&#xff1f; FLUX1.1 [pro]&am…