Koa

205 阅读7分钟

koa框架介绍

nodejs 是一个异步的世界,官方API支持的都是callback形式的异步编程模型,这会带来许多问题,例如:1.callback嵌套问题,2.异步函数中可能同步调用,返回数据,带来不一致性,为了解决上面问题,koa出来了

koa基于node.js平台的下一代web开发框架

koa是express原班人马打造致力成为一个更小,更富有表现力,更健壮的web框架,使用koa编写web应用,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率,koa不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写web应用变得得心应手,开发思路和express差不多,最大的特点就是可以避免异步嵌套

express 对比koa

编程模型不同

express的中间件是线型的,koa的中间件是u型的

对语言特性的使用不同

express使用回调函数next(),koav1.x使用generator语法, koav2.x使用async/await
2011-2016你很大概率会使用express/2017年你很大可能使用koa

koa的模型

koa环境搭建

1.安装ndoe.js 8以上的版本
开发koa2之前,nodejs是有要求的,它要求nodejs版本高于v7.6因为node.js7.6版本开始完全支持async/await,所以才能完全支持我们的koa2
2.安装koa框架
npm install koa --save npm install @types/koa --dev

await next

next() 表示进入下一个函数
下一个函数会返回一个Promise对象,称为p
下一个函数所有代码执行完毕后,将p置为成功
await会等待p成功后,再回头执行剩余的代码

app.use(async (ctx, next) => {
    const start = Date.now()
    await next()
    const time = Date.now() - start
    ctx.set('X-Response-Time', `${time}ms`)
})
//可以改写成
//app.use(async (ctx, next) => {
//    const start = Date.now()
//    return next().then(() => {
//        const time = Date.now() - start
//        ctx.set('X-Response-Time', `${time}ms`)
//    })
//})

koa api

app.env//获取环境变量
app.proxy//获取代理
app.listen()//监听一个端口
app.use(fn)//插入一个中间件
app.keys//用来加密的,部署的时候会用到
app.context//上下文
app.on('error',fn)//错误处理
app.emit //触发一个事件
ctx.req//nodejs封装的请求
ctx.request//koa封装的请求
ctx.res//nodejs封装的响应
ctx.response//koa封装的响应
ctx.state //跨中间件分享数据
ctx.cookies.get/set//设置或读取cookie
ctx.throw//抛出一个错误
ctx.assert//断言

koa路由

路由routing是一个URL和一个特定的HTTP方法(GET/POST等)组成的,涉及到应用如何响应客户端对某个网站节点的访问。
通俗的来讲:路由就是根据不同的URL地址,加载不同的页面实现不同的功能。
KOA中的路由和express有所不同,在express中直接引入express就可以配置路由,但是在koa中我们需要安装对应的koa-router路由模块来实现。

安装路由

npm install koa-router --save

//简单用法
const Koa = require('koa')
const router = require('koa-router')()
const app = new Koa()



router.get('/', async (ctx, next) => {
    ctx.body = '我是首页'//返回数据 类似原生res中的writeHead() res.end()
})
.get('/news', (ctx) => {
    const query = ctx.query //获取query对象
    const queryString = ctx.querystring//获取query字符串
    const url = ctx.url//获取url
    console.log(query)
    console.log(queryString)
    console.log(url)
    ctx.body = '这是新闻页面'
})
.get('/newscontent/:aid',async (ctx)=>{
    //获取动态路由
    const params = ctx.params//获取参数
    console.log(params)
    ctx.body = '新闻详情'

})
app
    .use(router.routes())//启动路由
    .use(router.allowedMethods())//可以配置也可以不配置,建议配置,这是官方推荐的用法,我们可以看到router.allowedMethods()用在了路由匹配router.routers()之后,所以在当所有路由中间件最后调用,此时根据ctx.status 设置response响应头

app.listen(3000)

koa 中间件

通俗的讲:中间件就是匹配路由之前或匹配路由完成做的一些列操作,我们就可以把它叫做中间件
在express中间件(middleware)是一个函数,他可以访问请求对象(request object(req)),响应对象(response object (res)),和web应用中处理请求-响应循环流程中的中间件,一般被命名为next的变量,在koa中间件和express有点类似。
中间件的功能包括:执行代码,修改请求和响应对象,调用堆栈中的下一个中间件。

应用级中间件

//匹配任何路由,匹配路由之前要做的操作,如果写这个路由被匹配到了就不会继续向下匹配
app.use(async (ctx,next)=>{
    console.log(new Date)//匹配路由前打印日期
    await next()//表示当前路由完成以后继续向下匹配
})

路由中间件

router.get('/', async (ctx, next) => {
    console.log('我是一个路由中间件')
    await next()//不写,就不会向下匹配哦
})
router.get('/', async (ctx, next) => {
    ctx.body = '首页呀'//返回数据 类似原生res中的writeHead() res.end()
})

错误处理中间件

router.get('/', async (ctx, next) => {
    console.log('我是一个路由中间件')
    ctx.body = '新闻页面'
})
app.use(async (ctx,next)=>{
    console.log('先执行use绑定的中间件,不管我写在上面还是下面')
    next()
    if(ctx.status === 404){
        ctx.body = '这是一个404页面'
    }
})

ejs模板

npm install ejs --save//安装ejs
npm install koa-views --save//安装koa-views
//绑定数据
<%=h%>
//绑定并且解析html字符串
<%-h%>
//if else
<%if(num>24){%>
    大于24
<%}else{%>
    小于24
<%}%>
//ejs文件内引入组件
 <%- include('public/header.ejs')%>
 //通过中间件在每一个路由的render里面都渲染一个公共数据
app.use(async(ctx,next)=>{
    ctx.state = {
        userName:'小可爱'
    }
    await next()
})

koa Post

原生js 在koa 中获取表单数据

exports.getPostData = function getPostData(ctx) {
    return new Promise((resolve, reject) => {
        let str = ''
        ctx.req.on('data', (chunk) => {
            str += chunk
        })
        ctx.req.on('end', () => {
            resolve(str)
        })
    })
}
router.post('/doLogin',async(ctx)=>{
    let data = await common.getPostData(ctx)
    ctx.body = data
})

使用koa-bodyparse中间件

npm install koa-bodyparser --save 
const bodyParser = require('koa-bodyparser')//引入bodyParser
router.use(bodyParser())//使用模块
router.post('/doLogin',async(ctx)=>{
    ctx.body = ctx.request.body//获取数据
})

koa-static静态资源中间件

npm install koa-static --save//安装
const static = require('koa-static')//引入
// app.use(static('./static'))//配置静态中间件,并且指定静态文件路径,,这种方法也行
app.use(static(__dirname+'/static'))
app.use(static(__dirname+'/other'))//可以去其他目录找,koa静态资源中间件可以配置多个

koa art-template

npm install art-template --save
npm install koa-art-template --save

demo链接

cookie

cookie 是储存在访问者计算机的变量,可以让我们用同一个浏览器访问同一个域名的时候数据共享。
http是无状态协议,简单的说,当你浏览了一个页面,然后转到同一个网页的另一个页面,服务器无法认识到这是同一个浏览器在访问同一个网站,都是没有任何关系的,cookie可以让我们用同一个浏览器访问同一个域名的时候共享数据,也就是保存用户信息

//设置cookie
ctx.cookies.set(name,value,{
    maxAge:'cookie过期的毫秒数',
    expires:'cookie过期的date',
    path:'cookie路径,默认是'/'',
    domain:'cookie域名',
    secure:'安全cookie默认false,设置成true表示只有https可以访问',
    httpOnly:'是否只是服务器可访问cookie,默认是true,false表示客户端 服务器端都可以访问',
    overwrite:'一个布尔值,表示是否覆盖以前设置的同名的cookie(默认false)
})'
//koa中获取cookie的值
ctx.cookies.get('cookieName')

koa-session的使用

session是另一种记录客户状态的机制,不同的是cookie保护在客户端浏览器中,session保存在服务器中。
session的工作流程
当浏览器访问服务器并发第一次请求是,服务器会创建一个session对象,生成一个类似于key,value的键值对,然后将key(cookie)返回到浏览器(客户端),浏览器下次再访问时,携带key(cookie);找到对应的session(value),客户的信息都保存在session中。

npm install koa-session --save
const session =require('koa-session')
const Koa = require('koa')
const app = new Koa()
app.keys = ['some secret hurr'+Math.random().toString()]//内容随便填,字符串加密
const CONFIG = {
    key: 'koa:sess',//默认
    maxAge: 86400000,//cookie过期时间 [需要修改]
    overwrite: true,//默认
    httpOnly: true,//true表示只有服务器端可以获取cookie
    signed: true,//默认签名
    rolling: true,//在每次请求时强制设置cookie,将重置cookie过期时间,默认为false [需要修改]
    renew: false//当cookie快过期的时候重新设置cookie [需要修改]
}
app.use(session(CONFIG, app))

demo链接