NodeJS KOA⑩②

news2024/11/14 14:54:34

文章目录

  • ✨文章有误请指正,如果觉得对你有用,请点三连一波,蟹蟹支持😘
  • 前言
  • KOA
  •     Koa vs Express
  •     Koa更轻量
  •     Koa~Context对象
  •     Koa~异步流程控制
  •     Koa~中间件模型
  • Koa路由
  •     1.1基本使用
  •     2.2请求方式
    • 2.2.1规范写法
    • 2.2.2拆分路由文件管理
  •    2.3 路由前缀
  •    2.4 路由重定向
  •    2.5 静态资源
  •    2.6 获取请求参数
  •    2.7 ejs模板
  •    2.8 Koa路由功能点合集练习
  • Cookie&Session
  •    Cookie
  •    Session
  • KOAJWT
  •    参数说明
  •    JWT函数封装
  •    练习演示
  • 上传文件
  • 操作MongoDB
  • KOA生成器 说明
  •     初始化结构
  •     App.js
  •     koa-json 中间件
  •     koa-onerror 中间件
  •     koa-bodyparser 中间件
  •     koa-logger 中间件
  • 总结


✨文章有误请指正,如果觉得对你有用,请点三连一波,蟹蟹支持😘

                    ⡖⠒⠒⠒⠤⢄⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸   ⠀⠀⠀⡼⠀⠀⠀⠀ ⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢶⣲⡴⣗⣲⡦⢤⡏⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠋⠉⠉⠓⠛⠿⢷⣶⣦⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀⠀⠀⠀⠀⠀⠘⡇⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠀⠀⠀⠀⠀⠀⠀⢰⠇⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⡴⠊⠉⠳⡄⠀⢀⣀⣀⡀⠀⣸⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀⠰⠆⣿⡞⠉⠀⠀⠉⠲⡏⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠈⢧⡀⣀⡴⠛⡇⠀⠈⠃⠀⠀⡗⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣱⠃⡴⠙⠢⠤⣀⠤⡾⠁⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢀⡇⣇⡼⠁⠀⠀⠀⠀⢰⠃⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⣸⢠⣉⣀⡴⠙⠀⠀⠀⣼⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⡏⠀⠈⠁⠀⠀⠀⠀⢀⡇⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⣰⠃⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⣀⠤⠚⣶⡀⢠⠄⡰⠃⣠⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢀⣠⠔⣋⣷⣠⡞⠀⠉⠙⠛⠋⢩⡀⠈⠳⣄⠀⠀⠀⠀⠀⠀⠀
⠀⡏⢴⠋⠁⠀⣸⠁⠀⠀⠀⠀⠀ ⠀⣹⢦⣶⡛⠳⣄⠀⠀⠀⠀⠀
⠀⠙⣌⠳⣄⠀⡇   不能   ⡏⠀⠀  ⠈⠳⡌⣦⠀⠀⠀⠀
⠀⠀⠈⢳⣈⣻⡇   白嫖 ⢰⣇⣀⡠⠴⢊⡡⠋⠀⠀⠀⠀
⠀⠀⠀⠀⠳⢿⡇⠀⠀⠀⠀⠀⠀⢸⣻⣶⡶⠊⠁⠀⠀
⠀⠀⠀⠀⠀⢠⠟⠙⠓⠒⠒⠒⠒⢾⡛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⣠⠏⠀⣸⠏⠉⠉⠳⣄⠀⠙⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⡰⠃⠀⡴⠃⠀⠀⠀⠀⠈⢦⡀⠈⠳⡄⠀⠀⠀⠀⠀⠀⠀
⠀⠀⣸⠳⣤⠎⠀⠀⠀⠀⠀⠀⠀⠀⠙⢄⡤⢯⡀⠀⠀⠀⠀⠀⠀
⠀⠐⡇⠸⡅⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⡆⢳⠀⠀⠀⠀⠀⠀
⠀⠀⠹⡄⠹⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⠸⡆⠀⠀⠀⠀⠀
⠀⠀⠀⠹⡄⢳⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⡀⣧⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢹⡤⠳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣷⠚⣆⠀⠀⠀⠀
⠀⠀⠀⡠⠊⠉⠉⢹⡀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡎⠉⠀⠙⢦⡀⠀
⠀⠀⠾⠤⠤⠶⠒⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠒⠲⠤⠽   

前言

  1. Node.js是一个javascript运行环境。它让javascript可以开发后端程序,实现几乎其他后端语言实现的所有功能,可以与```PHP、Java、Python、.NET、Ruby等后端语言平起平坐。
  2. Nodejs是基于V8引擎,V8是Google发布的开源JavaScript引擎,本身就是用于Chrome浏览器的JS解释,但是Node之父 Ryan Dahl在这里插入图片描述把这V8搬到了服务器上,用于做服务器的软件。

KOA


Koa2 :基于NodeJs 平台的下一代 web 开发框架

  • 简介

Koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。使用koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件(如 Static),它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。

  • 快速开始
    1. 初始化 → npm init
    2. 安装koa2 → npm install koa
    3. npm : https://www.npmjs.com/package/koa
    4. 相关库 : https://www.npmjs.com/search?q=koa

  • 生成器安装

    1. 局部安装 :npm install koa-generator
    2. 全局安装 :npm install -g koa-generator
    3. 创建项目 (koa1) koa projectName → (koa2) koa2 projectName

  • 入门演示
const Koa = require('koa')
const app = new Koa()
app.use(async ( ctx ) => {
ctx.body = 'hello koa2' //json数据 返回数据
})
app.listen(3000)
  • 服务器回调函数参数 说明 ↓
//koa回调函数参数 → ctx

//参数属性 如ctx.req 、 ctx.req 等于原生的Node属性 request、response对象
//既然使用了Koa应该避免Node属性 ↓
res.statusCode、res.writeHead()、res.write()、res.end()	

Koa参数属性,如ctx.request 、 ctx.response 等于 Koa的request对象、Koa的response对象
  • Koa访问器简写

在这里插入图片描述


    Koa vs Express

通常都会说 Koa 是洋葱模型,这重点在于中间件的设计。但是同步代码执行,会发现 Express 也是类似的,不同的是Express 中间件机制使用了 Callback 实现,这样如果出现异步则可能会使你在执行顺序上感到困惑,因此如果我们想做接口耗时统计、错误处理 Koa 的这种中间件模式处理起来更方便些。最后一点响应机制也很重要,Koa 不是立即响应,是整个中间件处理完成在最外层进行了响应,而Express 则是立即响应

    Koa更轻量

  1. koa 不提供内置的中间件;
  2. koa 不提供路由,而是把路由这个库分离出来了(koa/router)

    Koa~Context对象

  1. koa增加了一个Context的对象( == ctx参数),作为这次请求的上下文对象(在koa2中作为中间件的第一个参数传入)。同时Context上也挂载了Request和Response两个对象。和 Express类似,这两个对象都提供了大量的便捷方法辅助开发, 这样的话对于在保存一些公有的参数的话变得更加合情合理。

    Koa~异步流程控制

  1. express采用callback来处理异步, koa v1采用generator,koa v2 采用async/await。
  2. generator和async/await使用同步的写法来处理异步,明显好于callback和promise,

    Koa~中间件模型

  1. Express基于connect中间件,线性模型;
  2. Koa中间件采用洋葱模型(对于每个中间件,在完成了一些事情后,可以非常优雅的将控制权传递给下一个中间件,并能够等待它完成,当后续的中间件完成处理后,控制权又回到了自己)

洋葱图示 ↓

在这里插入图片描述

  • express 使用中间件

在这里插入图片描述

  • Koa中间件

在这里插入图片描述

代码演示

—Express同步—

const express = require("express")
const app = express()

app.use((req, res, next) => {
    if (req.url === "/favicon.ico") return
    console.log("111111")
    next()
    console.log("333333")
    res.send("hello world")
})

app.use((req, res, next) => {
    console.log("222222")
})

app.listen(3000)

// 输出
// 111111
// 222222
// 333333

—Koa同步—

const Koa = require("koa")
const app = new Koa()

app.use((ctx, next) => {
    if (ctx.url === "/favicon.ico") return
    console.log("111111")
    next()
    console.log("333333")
    ctx.body = "hello world"
})

app.use((ctx, next) => {
    console.log("222222")
})

app.listen(3000)
// 输出
// 111111
// 222222
// 333333

—Express异步—

const express = require("express")
const app = express()

app.use(async (req, res, next) => {
    if (req.url === "/favicon.ico") return
    console.log("111111")
    await next()
    console.log("4444444", res.token)
    res.send("hello world")
})

app.use(async (req, res, next) => {
    console.log("222222")

    //异步
    await delay(2000)

    res.token = "token~~"
    console.log("3333333")

})

function delay(time) {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, time)
    })
}

            // 111111
            // 222222
//期望输出 → 
            // 3333333 
            // 4444444 token~~

            // 111111
            // 222222
//实际输出 → 
            // 4444444 undefined
            // 3333333

app.listen(3000)

—Koa异步—

const Koa = require("koa")
const app = new Koa()

app.use(async (ctx, next) => {
    if (ctx.url === "/favicon.ico") return
    console.log("111111")
    var mytoken = await next()
    console.log("4444444", mytoken)
    ctx.body = "hello world"
})

app.use(async (ctx, next) => {
    console.log("222222")

    //异步
    await delay(1000)

    ctx.token = "token~~"
    console.log("3333333")
    return "token~~"
})

function delay(time) {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, time)
    })
}

app.listen(3000)

            // 111111
            // 222222
//期望输出 → 
            // 3333333 
            // 4444444 token~~

            // 111111
            // 222222
//实际输出 → 
            // 3333333 
            // 4444444 token~~

总结 :Express同步 VS Koa同步并没有特别大的区别,Express异步 VS Koa异步,Express会先执行next()下面的代码,而Koa会等待next()返回后再执行下面的代码。

注意 : koa使用时应加上Async Await

Koa路由


  • 快速开始

    1. 初始化 → npm install Koa-router
    2. 安装koa-router → npm install koa-router
    3. npm : https://www.npmjs.com/package/koa-router
    4. 相关库 : https://www.npmjs.com/search?q=koa-router

    1.1基本使用

var Koa = require("koa")
var Router = require("koa-router")
var app = new Koa()
var router = new Router()

使用

var Koa = require("koa")
var Router = require("koa-router")
var app = new Koa()
var router = new Router()
router.post("/list",(ctx)=>{
ctx.body=["111","222","333"]
})
//---路由使用---
app.use(router.routes()).use(router.allowedMethods())  //allowedMethods() 提示详细报错原因
或
app.use(router.routes())
app.use(router.allowedMethods())

app.listen(3000)

router.allowedMethods作用

  1. 不是使用router.allowedMethods → 如接口是post请求,你访问的是get请求 报错404
  2. 使用router.allowedMethods → 如接口是post请求,你访问的是get请求 提示 → "405 Method Not Allowed"

    2.2请求方式

Koa-router 请求方式: get 、 put 、 post 、 patch 、 delete 、 del ,而使用方法就是router.方式() ,比如 router.get() 和 router.post() 。而 router.all() 会匹配所有的请求方法。

代码演示

const Koa = require("koa")
const Router = require("koa-router")

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

//增 //ctx===context上下文
router.post("/list", (ctx, next) => { //添加数据
  ctx.body = {
    ok: 1,
    info: "add list success"
  }
}).get("/list", (ctx, next) => { //获取数据
  ctx.body = ["1111", "2222", "3333"]
}).put("/list/:id", (ctx, next) => { //更新数据
  console.log(ctx.params)
  ctx.body = {
    ok: 1,
    info: "put list success"
  }
}).del("/list/:id", (ctx, next) => { //删除数据
  ctx.body = {
    ok: 1,
    info: "del list success"
  }
})

app.use(router.routes()).use(router.allowedMethods())
app.listen(3000)

2.2.1规范写法

入口

const Koa = require("koa")
const app = new Koa()

const router = require("./routes") 

//应用级 使用中间件
app.use(router.routes()).use(router.allowedMethods())

//监听端口
app.listen(3000)

入口封装路管理由脚本

index.js

const Router = require("koa-router")
const userRouter = require('./user.js')
const listRouter = require('./list.js')
const homeRouter = require('./home.js')
......

const router = new Router()

//统一加前缀
// router.prefix("/api")

//先注册路由级中间件
router.use("/user", userRouter.routes(), userRouter.allowedMethods())
router.use("/list", listRouter.routes(), listRouter.allowedMethods())
router.use("/home", homeRouter.routes(), homeRouter.allowedMethods())

router.redirect("/", "/home") //重定向

module.exports = router

2.2.2拆分路由文件管理

user.js

//增
const Router = require("koa-router")
const router = new Router()

router.post("/", (ctx, next) => {
    ctx.body = {
        ok: 1,
        info: "add user success"
    }
}).get("/", (ctx, next) => {
    ctx.body = ["aaa", "bbbb", "ccc"]
}).put("/:id", (ctx, next) => {
    console.log(ctx.params)
    ctx.body = {
        ok: 1,
        info: "put user success"
    }
}).del("/:id", (ctx, next) => {
    ctx.body = {
        ok: 1,
        info: "del user success"
    }
})

module.exports = router

list.js

//增
const Router = require("koa-router")
const router = new Router()
router.post("/", (ctx, next) => {
    ctx.body = {
        ok: 1,
        info: "add list success"
    }
})
    .get("/", (ctx, next) => {
        ctx.body = ["1111", "2222", "3333"]
    })
    .put("/:id", (ctx, next) => {
        console.log(ctx.params)
        ctx.body = {
            ok: 1,
            info: "put list success"
        }
    })
    .del("/:id", (ctx, next) => {
        ctx.body = {
            ok: 1,
            info: "del list success"
        }
    })

module.exports = router

home.js

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

router.get("/", (ctx, next) => {
    ctx.body = `
    <html>
        <h1>home页面</h1>
    </html>
    `
})

module.exports = router

   2.3 路由前缀

router.prefix('/api')

   2.4 路由重定向

router.get("/home",(ctx)=>{
ctx.body="home页面"
})

//写法1
router.redirect('/', '/home');
//写法2
router.get("/",(ctx)=>{
ctx.redirect("/home")
})

   2.5 静态资源

  1. 安装koa-static→ npm install koa-static
  2. npm : https://www.npmjs.com/package/koa-static
const Koa = require("koa")
const app = new Koa()

const static = require("koa-static")
const path = require("path")

//应用级
app.use(static(path.join(__dirname, "public")))
app.listen(3000)

   2.6 获取请求参数

使用说明 👇👇👇

  • get请求获取参数

    在koa中,获取GET请求数据源头是koa中request对象中的query方法或querystring方法,query返回是格式化好的参数对象querystring返回的是请求字符串,由于ctx对request的API有直接引用的方式,所以获取GET请求数据有两个途径。

    1. 是从上下文中直接获取 请求对象ctx.query,返回如 { a:1, b:2 } 请求字符串 ctx.querystring,返回如 a=1&b=2
    2. 是从上下文的request对象中获取 请求对象ctx.request.query,返回如 { a:1, b:2 } 请求字符串 ctx.request.querystring,返回如 a=1&b=2

  • post请求获取参数
  1. 安装koa-bodyparser→ npm install koa-bodyparser
  2. npm : https://www.npmjs.com/package/koa-bodyparser
  3. 相关库:https://www.npmjs.com/search?q=koa-bodyparser

koa-bodyparser作用 :对于POST请求的处理,koa-bodyparser中间件可以把koa2上下文的formData数据解析到ctx.request.body中 .

使用

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

//导入库
const bodyParser=  require("koa-bodyparser")

// 使用ctx.body解析中间件
app.use(bodyParser())

router.post("/", (ctx, next) => {
    console.log(ctx.request.body) //获取前端传来参数
    ctx.body = {
        ok: 1,
        info: "add user success"
    }
})

   2.7 ejs模板

安装模块

koa-views模块 :https://www.npmjs.com/package/koa-views

koa-views相关模块 : https://www.npmjs.com/search?q=koa-views

安装koa模板使用中间件 :npm install --save koa-views

安装ejs模板引擎 :npm install --save ejs

  • 使用模板引擎

    1. 文件目录

在这里插入图片描述

  • 代码演示

./index.js文件

const Koa = require("koa")
const app = new Koa()

const static = require("koa-static")
const path = require("path")

const views = require("koa-views")

//应用级
app.use(static(path.join(__dirname, "public"))) //静态资源

//配置 模板引擎
app.use(views(path.join(__dirname, "views"), {
 extension: "ejs" 
 }))
app.listen(3000)

路由跳转代码

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

router.get("/",async (ctx)=>{
   await ctx.render("home",{username:"guoxiansheng	"}) //自动找views/home.ejs ,ejs参数
})

./view/index.ejs 模板

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ejs页面</title>
</head>

<body>
    <h1>home模板页面</h1>
    <div>欢迎<%= username%>回来</div>
</body>

</html>

   2.8 Koa路由功能点合集练习

app.js

const koa = require('koa')
const app = new koa()
const views = require('koa-views')
const path = require('path')
const static = require('koa-static')
const routes = require('./routers')
const bodyPar = require('koa-bodyparser')

app.use(bodyPar())
app.use(views(path.join(__dirname, 'views'), {
    extension: 'ejs'
}))
app.use(static(path.join(__dirname, 'public')))
app.use(routes.routes(), routes.allowedMethods())

app.listen(3000, () => {
    console.log("http://127.0.0.1:3000");
})

routers → index

const Router = require('koa-router')
const router = new Router()

const loginRouter = require('./login')

router.prefix('/api')
router.use('/login', loginRouter.routes(), loginRouter.allowedMethods())

module.exports = router

routers

const Router = require('koa-router')
const router = new Router()

router.get('/', (cxt) => {
    cxt.body = { "name": 'get' }
    console.log(cxt.query);
})

router.post('/', (cxt) => {
    cxt.body = { "name": 'post' }
    console.log(cxt.request.body);
})

// 模板引擎
router.get('/item', async (cxt) => {
    cxt.body = { "name": 'login ~ item' }
    await cxt.render("home")
})

//路由重定向 注意 ;重定向的路径最后必须带/
router.redirect('/items', '/item')

module.exports = router

views → home.ejs

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1>home模板页面</h1>
    <div>欢迎<%= %>回来</div>
</body>

</html>

public → login.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录</title>
</head>

<body>
    <button id="axiosG">axios get</button>
    <button id="axiosP">axios post</button>
    <button id="fetchG">fetch get</button>
    <button id="fetchP">fetch post</button>
</body>

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

<script>
    const axiosG = document.querySelector("#axiosG")
    const axiosP = document.querySelector("#axiosP")
    const fetchG = document.querySelector("#fetchG")
    const fetchP = document.querySelector("#fetchP")

    axiosG.addEventListener('click', () => {
        axios.get('/api/login?name=xiaoming&age=15').then((reason) => {
            console.log("axiosG  " + reason.data);
        })
    })
    axiosP.addEventListener('click', () => {
        axios.post('/api/login', {
            username: 'admin',
            password: 'admin'
        }).then((reason) => {
            console.log("axiosP  " + reason.data);
        })
    })
    fetchG.addEventListener('click', () => {
        fetch('/api/login?name=xiaoming&age=15').then(res => res.json()).then(data => {
            console.log("fetchG  " + data);
        })
    })
    fetchP.addEventListener('click', () => {
        fetch('/api/login', {
            method: 'post',
            body: JSON.stringify({
                username: 'admin',
                password: 'admin'
            }),
            headers: {
                "Content-Type": "application/json"
            }
        }).then(res => res.json()).then(data => {
            console.log("fetchP  " + data);
        })
    })
</script>

</html>

效果演示

在这里插入图片描述

Cookie&Session


   Cookie

  • cookie : koa提供了从上下文直接读取、写入cookie的方法
ctx.cookies.get(name, [options]) 读取上下文请求中的cookie
ctx.cookies.set(name, value, [options]) 在上下文中写入cookie

   Session


npm : https://www.npmjs.com/koa-session-minimal 🥄

KoaSession : koa-session-minimal 适用于koa2 的session中间件,提供存储介质的读写接口 。(自动储存操作cookie)

代码演示

//当置Session值时,会自动给前端设置cookie值
const session = require('koa-session-minimal')
app.use(session({
    key: 'SESSION_ID',
    cookie: {
        maxAge: 1000 * 60 //过期时间
    }
}))

session拦截器

const session = require("koa-session-minimal")

//session配置
app.use(session({
    key:"A#$A",
    cookie:{
        maxAge:1000*60*60 //一小时过期
    }
}))

//session判断拦截
app.use(async (cxt,next)=>{
    if(cxt.url.includes("login")){
        await next()
        return 
    }
    if(cxt.session.user){
        cxt.session.date=Date.now() //刷新时间
        await next()
    }else{
        cxt.redirect("/login")
    }
})

登录接口验证逻辑

router.post("/login", (ctx) => {
    const { username, password } = ctx.request.body
    if (username === "admin" && password === "123") {
        //设置sessionId
        ctx.session.user = {
            username: "admin"
        }
        ctx.body = {
            ok: 1
        }
    } else {
        ctx.body = {
            ok: 0
        }
    }
})

KOAJWT


  • npm : https://www.npmjs.com/package/jsonwebtoken

  • 模块安装 :npm install jsonwebtoken

   参数说明

---参数---
方法参数 : 
		value : 加密解密的值
		secret : 密钥内容 eg : id777888666 注意:加密和解密的密钥保持一致
		{expiresIn:1h} : 密钥过期时间 eg : 60, "2 days", "10h", "7d"
	

	const jwt = require("jsonwebtoken")
	const value = 'adwqeqwdsaewqcdsacascaseqwe'
	const secret = "id777888666"
---加密---
	
	jwt.sign(value,secret,{expiresIn:12d})

---解密---
	
	jwt.verify(value,secret)

   JWT函数封装

const jwt = require("jsonwebtoken")
const secret = "aii-anydata"
const JWT = {
    generate(value,expires){
        return jwt.sign(value,secret,{expiresIn:expires})
    },

    verify(value){
        try {
            return jwt.verify(value,secret)
        } catch (error) {
            return false
        }
    }
}

module.exports = JWT

   练习演示

接口逻辑

router.post("/login", (ctx) => {
    const { username, password } = ctx.request.body
    console.log(username);
    console.log(password);
    if (username === "123" && password === "123") {
    
        //设置HeaderTonken头信息
        const token = JWT.generate({
            _id: "111",
            username: "jiamijiemi"
        }, "10s")
        
        //token返回在header信息数据
        ctx.set("Authorization", token)

        ctx.body = {
            ok: 1
        }
    } else {
        ctx.body = {
            ok: 0
        }
    }

})

登录接口验证逻辑

app.use(async (ctx, next) => {
    //排除login相关的路由和接口
    if (ctx.url.includes("login")) {
        await next()
        return
    }
    
    const token = ctx.headers["authorization"]?.split(" ")[1]

    if (token) {
        const payload = JWT.verify(token)
        if (payload) {
            //重新计算token过期时间
            const newToken = JWT.generate({
                _id: payload._id,
                username: payload.username
            }, "10s") //10秒过期
            ctx.set("Authorization", newToken) //返回头信息
            await next()
        } else {
            ctx.status = 401
            ctx.body = { errCode: -1, errInfo: "token过期" } //前端接收到做处理 重定向
        }
    } else {
        await next()
    }
})

上传文件


npm : https://www.npmjs.com/package/@koa/multer

安装模块 : npm install --save @koa/multer multer

@koa/multer之前已做过详细的使用教程,这里就简单演示 ↓

语法

//单个文件
app.post('/profile', upload.single('avatar'), function (req, res, next) {

})
//多个文件,最多12,不写 → 无线
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {

})

代码演示

//1、引入@koa/multer
const multer = require('@koa/multer')
//2、配置资源存放文件夹
const upload = multer({dest:'public/uploads'})
//3、中间件使用
router.post('/',upload.single('avatar'),async (ctx)=>{

    await unloadMongodb.create({
        avatar : ctx.file?.filename ? `/uploads/${ctx.file.filename}` : '/images/default.png'
    })

    ctx.body={
        start:1,
        value:"add list success"
    }
})

操作MongoDB


npm : https://www.npmjs.com/package/mongoose

Mongoose之前已做过详细的使用教程,这里就简单演示 ↓

封装Mongoose数据库

const mongoose = require("mongoose")
mongoose.connect("mongodb://127.0.0.1:27017/kerwin_project")

const mongoose = require("mongoose")
const Schema = mongoose.Schema
const UserType = {
username:String,
password:String,
age:Number,
avatar:String
}
const UserModel = mongoose.model("user",new Schema(UserType))
// 模型user 将会对应 users 集合,
module.exports = UserModel

接口

//上传接口
router.post("/upload", upload.single("avatar"), async (ctx) => {
    console.log(ctx.request.body, ctx.file)
    const { username, password, age } = ctx.request.body
    const avatar = ctx.file ? `/uploads/${ctx.file.filename}` : ``

    //利用User模型进行存储操作 UserModel.create

    await UserModel.create({
        username,
        age,
        password,
        avatar
    })
    ctx.body = { ok: 1 }
})

KOA生成器 说明

    初始化结构

在这里插入图片描述

    App.js

const Koa = require('koa') //koa
const app = new Koa() //应用app
const views = require('koa-views') //静态视图配置
const json = require('koa-json') // ↓
const onerror = require('koa-onerror') // ↓
const bodyparser = require('koa-bodyparser')
const logger = require('koa-logger')

const index = require('./routes/index')
const users = require('./routes/users')

onerror(app)

//应用中间件
app.use(bodyparser({
  enableTypes: ['json', 'form', 'text']
}))
app.use(json())
app.use(logger())
app.use(require('koa-static')(__dirname + '/public')) //静态配置

app.use(views(__dirname + '/views', {
  extension: 'pug'
}))

app.use(async (ctx, next) => {
  const start = new Date()
  await next()
  const ms = new Date() - start
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})

app.use(index.routes(), index.allowedMethods())
app.use(users.routes(), users.allowedMethods())

app.on('error', (err, ctx) => {
  console.error('server error', err, ctx)
});
module.exports = app

    koa-json 中间件

koa-json中间件 有三个参数设置:

  1. pretty:是否格式化JSON,默认true

  2. param:是否格式化JSON,可选查询字符串,默认为空

  3. spaces:JSON空格,默认为2

  • 代码应用 1
const json = require('koa-json');
const Koa = require('koa');
const app = new Koa();

app.use(json({pretty: true}));

app.use((ctx) => {
    ctx.body = {value: 'value'};
});

//获取数据 ↓
//{
//  "value": "value"
//}
  • 代码应用 2
const json = require('koa-json');
const Koa = require('koa');
const app = new Koa();

app.use(json({pretty: true, param: 'pretty'}));

app.use((ctx) => {
    ctx.body = {value: 'value'};
});

//获取数据 ↓ 请求URL:/
//{"value":"value"}

//param: 'pretty' ↓  请求URL:/?pretty
//{
//  "foo": "bar"
//}

    koa-onerror 中间件

作用 : koa-onerror 可以在服务器产生错误(throw 抛出)→ 自动重定义到指定路径。

代码 ↓

const Koa = require('koa');
const app = new Koa();
const onerror = require('koa-onerror');
 
let onerrorConfig = {
    redirect: '/error' //重定义到error
}
 
onerror(app, onerrorConfig); //使用onerror

    koa-bodyparser 中间件

使用 👆👆👆

    koa-logger 中间件

作用 : koa-logger是一个koa下的日志打点中间件。

简单使用

//我们先简单了解下基本使用
const logger = require('koa-logger')
const Koa = require('koa')

const app = new Koa()
app.use(logger()) // 建议在最顶层中间件接入

总结

以上是个人学习Node的相关知识点,一点一滴的记录了下来,有问题请评论区指正,共同进步,这才是我写文章的原因之,如果这篇文章对您有帮助请三连支持一波

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

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

相关文章

数据结构——带头节点的双向循环列表

带头节点的双向循环链表是一种特殊的双向链表&#xff0c;它与普通的双向链表相比&#xff0c;最大的区别是链表头结点的 next 指针不再指向第一个实际节点&#xff0c;而是指向链表中的第一个节点。同时&#xff0c;链表尾结点的 prev 指针也不再指向 NULL&#xff0c;而是指向…

轻松配置深度学习模型 ?

动动发财的小手&#xff0c;点个赞吧&#xff01; 由于所有模块都需要大量参数和设置&#xff0c;因此管理深度学习模型可能很困难。训练模块可能需要诸如 batch_size 或 num_epochs 之类的参数或学习率调度程序的参数。同样&#xff0c;数据预处理模块可能需要 train_test_spl…

Java接口幂等性,如何重试?

Java接口幂等性&#xff0c;如何重试&#xff1f; 文章目录 Java接口幂等性&#xff0c;如何重试&#xff1f;前言一、幂等性是什么&#xff1f;二、为什么要幂等性&#xff1f;三、使用什么办法实现幂等性&#xff1f;1.insert前先select2.加悲观锁3.加乐观锁4.加唯一索引5.Re…

uniapp系列-uni.getAppBaseInfo() versionCode appVersion 值不对应该怎么解决?

今天看到一个BUG 问题描述 我们使用uniapp的官方文档中uni.getAppBaseInfo()后获取的 appVersionCode appVersion &#xff0c;发现获得的结果和我们实际设置的不一致&#xff0c;不是manifest.json里面的值&#xff0c;如下图所示官方文档&#xff1a;https://uniapp.dcloud…

还原大师(MD5)

根据题目提示&#xff0c;都猜得到这应该跟MD5的加密形式有关系 我好像还没有具体了解过MD5编码的格式&#xff0c;或许本题可以通过MD5的编码格式推导出字符串 但是说实话&#xff0c;MD5的加密方式没有找到详细简介的文章 然后我就去网上百度了一下&#xff0c;经过大佬wp的洗…

java springboot整合MyBatis演示增删查改操作

前面我的文章 java springboot整合MyBatis做数据库查询操作讲述了整合springboot整合MyBatis 做了根据id查询的语句 那么 我们现在按它搭建的项目继续 我们在staffDao中添加一个insert函数 参考代码如下 Insert("insert into staff(name, age, status, departmentid) va…

chatgpt赋能python:Python编程实现1+22+333,解密方法

Python编程实现122333&#xff0c;解密方法 在Python编程开发中&#xff0c;我们经常需要求解不同类型的算数表达式&#xff0c;其中求解一系列类似122333的表达式是一个比较常见的需求。本文将会介绍如何使用Python语言方便地求解这类表达式&#xff0c;为大家提供一种针对此…

Redis中AOF和RDB

在Redis的持久化中&#xff0c;常使用的两个手段便是AOF和RDB进行持久化。 RDB&#xff08;Redis DataBase&#xff09;是Redis的持久化方式之一&#xff0c;在配置文件中&#xff0c;我们可以找到 对Redis进行持久化配置&#xff0c;而RDB在持久化时是怎么样进行工作的呢&…

ARM、ARM架构、ARM架构芯片

ARM是一种基于精简指令集&#xff08;RISC&#xff09;的处理器架构&#xff0c;它由英国的ARM公司设计和授权。 ARM芯片具有低功耗、高性能、高集成度等特点&#xff0c;广泛应用于嵌入式系统、移动设备、物联网、服务器等领域。本文将介绍ARM的各类芯片&#xff0c;包括其特…

Java-API简析_java.lang.ClassLoader类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/131345825 出自【进步*于辰的博客】 其实我的【Java-API】专栏内的博文对大家来说意义是不大的。…

CentOS 7.9 安装 Jenkins

CentOS 7.9 安装 Jenkins 文章目录 CentOS 7.9 安装 Jenkins一、概述二、安装1、安装 OpenJDK2、安装 Jenkins3、启动 Jenkins4、给 Jenkins 放行端口 三、初始化 Jenkins 配置1、访问2、解锁 Jenkins3、配置清华大学的源地址4、安装插件5、创建管理员用户6、完成安装 四、功能…

TypeScript ~ TS 掌握自动编译命令 ③

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; TypeScript ~ TS &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &…

锐捷睿易:云端绑定别人账号,命令方式解绑

一、适用场景 云端绑定了别人的账号&#xff0c;但又不能让他解绑&#xff0c;只能自己解绑从新绑定自己MACC 前提&#xff1a;需要设备联网状态才可以解绑 二、配置步骤 1、登录macc&#xff0c;首页点击设备解绑 2、输入收集的设备序列号&#xff0c;点击获取专属URL&…

chatgpt赋能python:Python清空console的方法

Python清空console的方法 随着Python的应用越来越广泛&#xff0c;我们经常会遇到需要清空Python console的情况。比如&#xff0c;我们可能需要重新开始一段代码的执行&#xff0c;或者想要隐藏过去的交互记录。在这篇文章中&#xff0c;我们将介绍几种方法来清空Python cons…

安装配置nvm-windows对Node.js与npm进行版本控制

一、nvm 由于Node.js版本原因&#xff0c;可能会出现一些错误&#xff0c;如IDEA中Node.js环境下npm报错Error:0308010C:digital envelope routines:unsupported。而且不同的项目&#xff0c;所采用的Node.js的版本不同&#xff0c;重新卸载安装配置&#xff0c;太过繁琐。所以…

chatgpt赋能python:Python求加速度:从计算机视觉到自动驾驶

Python求加速度&#xff1a;从计算机视觉到自动驾驶 在计算机视觉、自动驾驶和机器人等领域&#xff0c;求加速度是常见的任务。Python是一种强大的编程语言&#xff0c;可以用于快速、简便地求解加速度。本篇文章将介绍如何在Python中求解加速度&#xff0c;并探讨加速度在实…

【无标题】很有趣的一个个CSS小球下落动画

代码如下 <!-- 两个div --> <div class"ball"></div> <div class"ground"></div>.ball {width: 30px;height: 30px;background-color: black;border-radius: 50%;position: relative;left: 90px;animation: failing 0.5s ea…

leetcode64. 最小路径和(动态规划-java)

最小路径和 leetcode64. 最小路径和题目描述 暴力递归 缓存代码演示 动态规划代码演示空间压缩代码演示 动态规划专题 leetcode64. 最小路径和 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/minimum-path-sum 题目描…

C高级6.23

一.整理用户相关的指令、整理磁盘相关的指令 用户相关的指令&#xff1a; 1.id -u 查看用户ID 2.id -g 查看组ID 3.whoami 查看用户名 4.sudo adduser 用户名 创建用户 5.给新用户添加sudo权限 给新用户添加sudo权限的步骤&a…

Spring 与 Servlet-1

整合 Spring 和 Servlet DAO 使用 JDBC 通过模板类进行整合&#xff0c;模板类由 Spring 框架提供&#xff0c;只需进行配置即可 1、依赖&#xff1a;spring-jdbc 和连接池 druid、数据库驱动 mysql-connect-java 2、引入了 IoC、DI 后对象的创建完全交给 Spring 负责&#…