koa2 快速上手

news/2025/1/13 6:33:08/

1.koa2简介:

koa2是由express原开发人员开发的,是为了解决Express处理异步回调嵌套过深的问题的node服务端开发框架,最初是第一版被称为koa,koa存在Generator+yield不太好的地方,后来就出现第二版koa2,koa2中支持async/await,但是我express项目中也是在用async/await。

2.koa2特点:

支持async/await语法糖、支持洋葱模型的中间件。

洋葱模型中间件:web服务器在处理一个又一个的请求并作出响应时,在这个过程中需要程序处理,这个处理的程序被称为中间件,多个中间件在处理的过程中是由外到内,在由内到外的过程,从请求到响应可以理解为竹签穿过洋葱,洋葱每层表示一个中间件。

3.koa2快速上手:

1.安装koa2:npm install koa,下载时无需写koa2,下载时会自动下koa2。

2.创建koa对象,编写响应函数(中间件)

3.监听端口,启动程序,具体如下代码:

const koa = require('koa')
// 创建koa对象
const app = new koa()
// 挂载中间件:(中间件实际就是一个处理并返回结果的函数,可能你不需要写return,但是ctx中也是会返回数据),实际开发中会将中间件抽离到单独的文件中,之后挂载到app上
app.use((ctx,next) => {// ctx表示上下文,可以调用到请求对象和响应对象,next表示下一个中间件的执行console.log(ctx.request.url)// 设置响应体:ctx.response.body = 'hello word!'// 调用下一中间件执行: (从上到下一次执行中间件,但是是在调用next的情况下才会执行)console.log('第一层中间件1')next()console.log('第一层中间件2')return '第一层'
})
// 又一层中间件:
app.use((ctx, next) => {console.log('第二层中间件1')next()console.log('第二层中间件2')return '第二层'
})// 执行顺序:第一层中间件1-------第二层中间件1---------第二层中间件2--------第二层中间件1,洋葱模型,从外到里,在从内到外// 监听服务启动:
app.listen(3000)

4.项目中使用koa:

本项目也是一个demo,实际中可能有很多种处理中间件,在这里我我使用三个中间件处理数据,分别是计算耗时中间件、设置响应头中间件、处理业务中间件(登录接口实现)

总耗时中间件:

module.exports = async (ctx, next) => {// 每次请求先记录一次时间:const start = Date.now()// 让内层中间件执行,此过程会耗时,内层中间件执行完后,下面的代码才会执行,所以在next后面再次获取当前时间,之后做减法就是总耗时await next()//通常情况下中间件中有异步,所以这里使用async/awaitconst end = Date.now()const totalTime = end - start// 将总耗时设置给响应头:ctx.set('X-Response-Time', totalTime + 'ms')
}

设置响应头中间件:

module.exports = async (ctx, next) => {// 统一设置响应数据类型为:json格式const contentType = 'application/json; charset=utf-8'ctx.set('Content-Type', contentType)// 解决跨域:ctx.set('Access-Control-Allow-Origin','*')ctx.set('Access-Control-Allow-Methods','OPTIONS, GET, PUT, POST, DELETE')await next()
}

app.js入口文件:

// 引入计算总耗时的中间件:
const duiringTime = require('./middleware/duringtime')
// 引入设置响应头的中间件:
const setResponseHeader = require('./middleware/setresponseheader')
// 引入解析请求体的中间件:koa-bodyparser
const bodyParser = require('koa-bodyparser')
// 导入登录路由
const loginserve = require('./serves/loginserve')const Koa = require('koa')
// 创建Koa实例对象:
const app = new Koa()// 绑定计算耗时的中间件:
app.use(duiringTime)
// 挂载设置响应头的中间件:
app.use(setResponseHeader)
// 挂载bkoa-bodyparser中间件:如果不配置的话在路由页就不能通过ctx.request.body拿到请求体
app.use(bodyParser())// 挂载登录接口路由:
app.use(loginserve.routes())// 绑定端口号:
app.listen(3000,() => {console.log('serve is running at 3000!')
})

loginserve登录接口文件:

// 引入路由模块:
const Router = require('koa-router')
// 引入数据库配置
const connection = require('../config/mysqldbconfig')
//引入token工具
const {createToken} = require('../commethods/creattoken')
// 创建路由实例:
const router = new Router({prefix:'/api'})//里面可接收一个对象,可以设置些默认配置,如{prefix:'/api'}设置路由匹配前缀// 实现一个登录接口:
// 在创建路由时默认加了前缀 /api ,下面router.post('/login', ()=>{})可直接匹配:'/api/login'路由
router.post('/login',async (ctx, next) => {let {userName, userPassword} = ctx.request.bodylet sql = 'SELECT `user_password`,`user_id`,`user_name` FROM theuser WHERE user_name = "'+userName+'"'// 这里不能像express中直接对数据库进行操作,否则响应拿不到查询结果,这里必须使用异步,将查询封装到一个异步函数中,之后在这里使用await调用封装的函数,如:// 封装查询函数(可以抽离到单独的文件中):function isLogin (sql){return new Promise((resolve,reject) => {connection.query(sql,(error, result) => {if (error) {reject()} else {resolve(result)}})})}// 调用查询函数let results = await isLogin(sql)// 响应:用户名存在时:if (results.length > 0) {// 且密码正确时:if (results[0].user_password === userPassword) {// 生成token规则let rule = {id:results[0].user_id,naems:results[0].user_name}// 生成token并响应:let token = createToken(rule)ctx.body = {cod: 200, msg: '登录成功!', userId: results[0].user_id, token: token}} else {ctx.body = {cod: 201, msg: '密码错误!'}}}  else {// 用户名不存在时:ctx.body ={cod: 202, msg: '用户不存在!'}}// 经测试,直接return一个Promise也可以在响应时拿到结果,查阅资料都是以上方式实现的return new Promise((resolve,reject) => {connection.query(sql, (error, results) => {try {if (error) {throw error} else {// 用户名存在时:if (results.length > 0) {// 且密码正确时:if (results[0].user_password === userPassword) {// 生成token规则let rule = {id:results[0].user_id,naems:results[0].user_name}// 生成token并响应:let token = createToken(rule)ctx.body = {cod: 200, msg: '登录成功!', userId: results[0].user_id, token: token}} else {ctx.body = {cod: 201, msg: '密码错误!'}}}  else {// 用户名不存在时:ctx.body ={cod: 202, msg: '用户不存在!'}}resolve()}} catch (err){reject()console.log('loginserve文件login登录接口错误:' + err)}})})
})// 导出路由
module.exports = router

提示:数据库配置文件,生成token的文件我这里没有粘出

提示:本文图片等素材来源于网络,若有侵权,请发邮件至邮箱:810665436@qq.com联系笔者 删除。

笔者:苦海


http://www.ppmy.cn/news/498140.html

相关文章

2021-最新Web前端经典面试试题及答案-史上最全前端面试题(含答案)---Node篇

★★★ 如何使用原生 Node.js 操做 cookie? ★★ 什么是 Node.js?我们在哪里使用它? ★★ 为什么要使用 Node.js? ★★★ Node.js 有哪些特点? ★★★ setImmediate 和 setTimeOut 区别在哪里? ★★★ 如何更新 …

第八-九周-总结(day38-54)

HTML 一、html结构 <!DOCTYPE html> h5默认的文档声明<html> html根标签<head> 头标签<meta charset"utf-8"> 页面编码格式所有的现代浏览器:谷歌/火狐/IE8以上的/欧鹏浏览器/洋葱浏览器/windows自带的edge 浏览器识别的编码:utf-…

vue+Nodejs+Koa搭建前后端系统(二)--koa-generator创建项目及分析

前言 采用上一篇vueNodejsKoa搭建前后端系统&#xff08;一&#xff09;–简易版创建的项目目录的基础上&#xff0c;创建新的后端服务项目server2使用koa-generator脚手架创建后端项目计算机系统为Windows 10 专业版 小说中&#xff0c;终成眷属一般就结局了&#xff0c;但现…

文件下载,搞懂这9种场景就够了

在 文件上传&#xff0c;搞懂这8种场景就够了 这篇文章发布之后&#xff0c;阿宝哥收到了挺多掘友的留言&#xff0c;感谢掘友们一直以来的鼓励与支持。那我们就来整一篇文章&#xff0c;总结一下文件下载的场景。 一般在我们工作中&#xff0c;主要会涉及到 9 种文件下载的场景…

鄙视那些把爬虫当作AI的SB,清华学霸尹成大哥的历史上最强大的爬虫视频

人类有史以来最强悍的爬虫视频&#xff0c;尹成大魔不出&#xff0c;谁与争锋 清华学霸尹成大哥的Python爬虫视频&#xff0c;近期免费公开&#xff0c;可以找客服475318423索要视频源码。 爬虫基础 1.爬虫的定义与作用 2.截取http协议-Fiddler实战 get与post差别 3.如何…

【Web技术】1016- 全面理解 8 种文件上传场景

在日常工作中&#xff0c;文件上传是一个很常见的功能。在项目开发过程中&#xff0c;我们通常都会使用一些成熟的上传组件来实现对应的功能。一般来说&#xff0c;成熟的上传组件不仅会提供漂亮 UI 或好的交互体验&#xff0c;而且还会提供多种不同的上传方式&#xff0c;以满…

【NodeJS】关于Node.js Web框架Koa的中间件编写以及如何理解洋葱模型

文章目录 Koa入门1.1 中间件的使用1.2 路由该怎么写1.2.1 原生路由1.2.2 利用koa-router中间件实现1.2.3 文件路径匹配路由 1.3 静态服务器1.3.1 koa-static中间件使用1.3.2 实现一个静态服务器 1.4 模板引擎1.4.1 ejs模板使用1.4.2 pug模板使用 1.5 处理请求数据1.5.1 get请求…

多线程并发和多任务并行的小结

一、多线程并行的一点小结 1.无论是thread::spawn还是tokio::spawn,都是创建一个线程或者任务去执行闭包的函数体。thread::spawn接受一个闭包作为参数&#xff0c;并返回一个 JoinHandle&#xff0c;其中 T 是闭包的返回类型。创建的新线程将在后台运行&#xff0c;并执行闭包…