koa2 快速上手
Posted 苦海123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了koa2 快速上手相关的知识,希望对你有一定的参考价值。
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/await
const 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.body
let 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联系笔者 删除。
笔者:苦海
以上是关于koa2 快速上手的主要内容,如果未能解决你的问题,请参考以下文章