1. 概述

Koa的设计思想是中间件,类似于流水线。涉及数据交互cookiesessionrouter以及模板引擎。koa v1基于generatorkoa v2基于generator + async + awaitkoa v3基于await

2. 搭建简单服务器

npm i koa koa-static koa-better-body koa-convert koa-router

koa:主体,自身带cookie功能。

koa-static:静态文件。

koa-better-body:管理请求,getpostupload

koa-convert:中间件过度koa版本兼容。

koa-router:路由。

koa丢弃了原生node的写法,express保留原生node写法,koa强依赖router,必须用router

const koa = require('koa');
const router = require('koa-router');
const server = new koa();
server.listen(8080);

const rout1 = router();
server.use(rout1.routes());
rq.get('/a', async (ctx, next) => {
    // ctx.req 原生req对象
    // ctx.request 封装好的req对象
    // ctx.res 原生的res
    // ctx.response 封装好的response
    // ctx.request.headers 获取请求头
    ctx.response.status = 403; // 设置状态码
    ctx.response.set('a', 12); // 设置响应头
    ctx.response.body = 'abc'; // 设置返回参数
})

// const router = require('koa-router');
// const r1 = router();
// server.use(r1.routes());
// r1.get(路径, async() => {})
// r1.post(路径, async() => {})
// r1.put(路径, async() => {})
// r1.delete(路径, async() => {})
// r1.use(路径, async() => {})

3. 静态资源

const static = require('koa-static');
server.use(static(path.resolve('www'));

koa-static返回的文件没有压缩,不建议使用,想要压缩需要传入gzip: true,后缀名用gz不过太麻烦了可以用koa-static-cache

npm install koa-static-cache --save
const static = require('koa-static-cache');
server.use(static(path.resolve('www'));

4. 请求数据

动态路由,路由参数在ctx.params中。

const betterBody = require('koa-better-body');
const convert = require('koa-convert');
server.use(r1.routes());
server.use(convert(betterBody({
    uploadDir: path.resolve('./upload'),
    keepExtensions: true
}))); // 使用convert将老的中间件,支持最新的功能
r1.get('/api/:name', async (ctx, next) => {
    console.log(ctx.params);
})

ctx.request.fields; // 既有普通参数,又有附件参数
ctx.request.files; // 只有附件信息

5. cookie

koa自带cookie,直接可以使用ctx.cookies

ctx.cookies.get('key')获取cookie

ctx.cookies.set('b', 5, {})设置cookie

6. session

需要手动安装koa-session插件

const session = require('koa-session');
// session 必须加要一组keys,防止被劫持
server.keys = ['fsdfsfsdfdfds', 'vbcbfgbdvdfbfdb', 'nnhgnhtfsfsdfsd'];
// 需要参数,并且还要吧server实例传入进去
server.use(session({}, server));
server.use(async (ctx) => {
    if (ctx.session['count']) {
        ctx.session['count']++;
    } else {
        ctx.session = 1;
    }
});

7. mysql

需要安装mysql-prokoa-mysql版本太低,不支持await,所以被弃用了。

const MySql = require('mysql-pro');
const db = new MySql({
    mysql: {
        host: '',
        port: 3306
        user: '',
        password: '',
        database: 'eat'
    }
})
server.use(async ctx => {
    const data = await db.query('select * from ')
})

8. 服务端渲染

需要安装 koa-ejskoa-pug

pug

const Pug = require('koa-pug');
const pug = new Pug(
    viewPath: path.resolve('template'),
    app: server // pug.use(server);
)

server.use(async ctx => {
    await ctx.render('模板名称', { a: 123});
})

ejs

const ejs = require('koa-ejs');
ejs(server, {
    root: path.resolve('template'),
    layout: false,
    viewExt: 'ejs' // 扩展名
})
server.use(async ctx => {
    await ctx.render('modal_name', {name: 1, age: 18})
})

9. 服务结构

const Koa = require('koa');
const Router = require('koa-router');
const static = require('koa-static-cache');
const body = require('koa-better-body');
const convert = require('koa-convert');
const Mysql = require('mysql-pro');
const session = require('koa-session');
const ejs = require('ejs');
const path = require('path');

const db = new Mysql({
    mysql: {
        host:'',
        port: '',
        user: '',
        password: '',
    }
});
db.execute = async (sql) => {
    let res = '';
    await db.startTransaction();
    if (typeof sql === 'string') {
        res = await db.executeransaction(sql);
    } else {
        sql.forEach(async item => {
            res = await db.executeransaction(item);
        })
    }
    await db.startTransaction();
    return res;
}

const server = new Koa();
server.listen(8080);
// 日志
server.use(async (ctx, next) => {
    fs.appendFile('logs/2018-1-1', `[2018-10-1] 地址 url \r\n`, async err => {
        await next();
    })
})
// 错误处理,捕获所有的异常
server.use(async (ctx, next) => {
    try {
        await next();
    } catch(e) {
        ctx.response.body = '服务器正在维护';
        console.log('出错了')
    }
})
server.use(convert(body({
    uploadDir: path.resolve('www/upload')
})))
server.keys = ['dadasdad','evreregfd'];
server.use(session({}, server))
ejs(server, {
    root: path.resolve('template'),
    layout: false,
    viewExt: 'ejs.html',
    cache: false,

})
const r1 = new Router();
server.use(async (ctx, next) => {
    ctx.db =db; // 将数据链接绑定到全局
    await next();
})
server.use(r1);
server.use(static(path.resolve('www')));
r1.get('/a', ctx => {
    const data = await ctx.db.execute('select * from lalala')
    await ctx.render('list', data)
})

转载须知

如转载必须标明文章出处文章名称文章作者,格式如下:

转自:【致前端 - zhiqianduan.com】 koa简单介绍  "隐冬"
请输入评论...