02-Koa2

nobility 发布于 2020-07-04 2167 次阅读


Koa2

使用npm install koa命令安装koa2框架,以下简单是使用方式

const koa = require("koa");
const app = new koa();  //创建服务器对象,相比express多了一个new关键字
app.listen(8000);  //该对象监听8000端口
console.log('Server running at http://127.0.0.1:8000/');

中间件机制

沿用Express中的中间件机制,Koa并没有捆绑任何中间件,所有中间件都是单独的中间件包需要时另外引入即可,只有use()方法,并且不能指定第一个参数为请求路径(会报错),只能是一个方法,没有像express那样get()post()等方法,这些方法被抽取到了koa-router路由中

通过利用async函数,从而摈弃掉回调函数,并有力地增强错误处理,所以中间件必须是一个async函数,该回调函数共有两个参数:

  • ctx:ctx是context(上下文)的简写,是客户端请求对象和服务器响应对象的结合体,其中的一些方法或属性为请求对象或响应对象的别名
    • ctx.req:客户端请求对象
    • ctx.res:服务器响应对象
    • ctx.path:请求路径别名
    • ctx.method:请求方法别名
    • ctx.query:请求查询字符串对象
    • ctx.body:返回的内容主题,可以是字符串,可以是对象格式(会自动转化为json)
  • next:默认情况下中间件依次向下匹配,一旦匹配成功就终止匹配
    • 若再调用next()方法就会接着向下匹配
    • 若在使用await next()方法就会先向下匹配,终止匹配后在回来,也就是洋葱圈模型

错误处理中间件

由于中间件处理函数都是async函数,所以不能向下传递错误对象,只要监听error事件即可,使用try...catch捕获的错误不会触发error事件,切忌不要在async函数中使用异步回调,否则会error事件不会触发

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

路由中间件

Koa并没有捆绑任何中间件,路由中间件需要独立安装,使用npm install koa-router安装路由中间件,再创建路由对象实例,此时的路由是一个对象,而中间件是一个方法,所以在调用路由对象的routes()方法即可返回路由中间件

所有路由路径都要以/开头,路由对象的作用就是为了才拆分不同路由,以实现模块化管理,基本使用如下:可以拆分多级路由

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


const koaRouter = require('koa-router');
const homeRouter = new koaRouter();    //创建路由对象
homeRouter.get("/index.html", async (ctx, next) => {  //使用路由对象进行请求响应
    ctx.body = "hello";
})


app.use(homeRouter.routes()); //注册路由中间件
//routes()方法返回路由中间件,即注册路由中间件
app.use(homeRouter.allowedMethods());
//官方推荐在注册路由后使用该方法注册再中间件
//allowedMethods()方法返回单独的中间件,会自动根据响应状态码设置响应体

app.listen(8000);
console.log('Server running at http://127.0.0.1:8000/');

请求和响应

方法名 描述
router.use([path,]...callback) 添加路由级别的中间件
router.prefix(prefix) 设置路由的路径前缀路径
router.get([path,]...callback) get请求方法的中间件
router.post([path,]...callback) post请求方法的中间件
router.put([path,]...callback) put请求方法的中间件
router.del([path,]...callback) del请求方法的中间件
router.all([path,]...callback) 所有请求方法的中间件

上下文对象

请求
属性或方法 描述
ctx.query 请求查询字符串对象
ctx.params 路由参数对象,在请求路径中使用/:id其中id就是一个路由参数,该参数存储在params对象中
ctx.request.body post请求的请求体,无法直接使用,需要先安装koa-bodyparser包,再post请求之前添加该中间件即可,具体参考下面代码
const bodyparser = require("koa-bodyparser");
app.use(bodyparser({
  enableTypes:["json", "form", "text"]	//可解析的post请求格式
}))
响应
属性或方法 描述
ctx.body 返回的内容主题,可以是字符串,可以是对象格式(会自动转化为json)
ctx.status 设置响应状态码
ctx.redirect(url) 重定向
ctx.attachment(filename) 发送附件,即下载文件
ctx.cookies.get(name,[options]) 获取cookie
ctx.cookies.set(name,value[options]) 设置cookie

静态资源托管中间件

Koa并没有捆绑任何中间件,静态资源托管中间件需要独立安装,使用npm install koa-static安装静态资源托管中间件,之后使用与express使用方式一致了

const path = require("path");
const static = require('koa-static')
app.use(static(path.join(__dirname, "public"), {
    index: "index.html",	//默认首页
    maxAge: 24 * 60 * 60 * 1000	//将静态文件缓存浏览器的时间,单位毫秒
}));

其他常用中间件

session

在请求对象中添加的session信息(ctx.session),需要先使用npm install koa-generic-session 安装koa-generic-session包,再请求之前添加该中间件即可,具体参考下面代码

/***********解析 ctx.session 模块************/
const session = require("koa-generic-session");
app.keys = ["pwd"];	//设置加密密钥
app.use(session({
  key: 'session',	//cokkie中存储的sessionId前缀,会有两个键值,默认是koa,分别是koa.sid和koa.sid.sig
  cookie: {
    // path: '/',	//session作用范围,默认就是 /
    // httpOnly: true,	//只允许服务端修改,默认就是true
    maxAge: 30 * 1000	//session失效时间,单位毫秒
  }
}))

/***********解析 ctx.session 模块存入redis中的配置,需要在安装koa-redis包************/
const session = require("koa-generic-session");
const redisStore = require("koa-redis");
app.keys = ["pwd"];	//设置加密密钥
app.use(session({
    key: 'session',	//cokkie中存储的sessionId名
    cookie: {
        maxAge: 30 * 1000	//session失效时间,单位毫秒
    },
    store: redisStore({
        all: "127.0.0.1:6379"   //redis地址
    })
}));

日志记录

使用npm install koa-morgan安装该中间件,再请求之前添加该中间件即可,使用方式与express一致,具体参考express中的日志记录即可

文件上传

使用npm install koa-multer安装该中间件,再请求之前添加该中间件即可,使用方式与express一致,具体参考express中的文件上传即可,要注意的是需要使用async函数,对于请求和响应对象使用ctx.reqctx.res即可

jsonp

使用npm install koa-jsonp安装jsonp中间件,再请求之前添加该中间件即可,对于jsonp的请求会自动按照jsonp格式返回,具体可参照下面代码

const json = require("koa-json");
app.use(json());
app.use( async ( ctx ) => {
  ctx.body = {}  //对于jsonp的请求会直接返回jsonp格式JavaScript代码
})

模板引擎

需要安装使用npm install koa-views安装模板引擎中间件,同时需要安装要用的模板比如ejs,使用npm install ejs安装,再请求之前添加该中间件即可,具体参考下面代码

const views = require('koa-views');
const viewsPath = path.join(__dirname, 'view');
app.use(views(viewsPath, {
    extension: 'ejs'
}))
app.use(async (ctx, next) => {
    await ctx.render("index", { msg: "message" });	//若有目录则需要指定目录dir/index
  	//使用index模板进行渲染,并指定数据对象
})

koa-views仅支持ejs、pug等一些引擎,若想使用art-template模板需要使用npm install koa-art-template安装该模板引擎,注册中间件方式有所不同,具体参考下面代码,该模板引擎的具体使用方法从官网可以获得

const render = require("koa-art-template");
render(app, {
    root: path.join(__dirname, "view"),	//模板文件目录
    extname: ".art",	//后缀名
    debug: process.env.NODE_ENV !== "production"	//开启非生产环境下的debug模式
});

app.use(async function (ctx, next) {
    await ctx.render("index", { msg: "message" });	//若有目录则需要指定目录dir/index
  	//使用index模板进行渲染,并指定数据对象
});

koa生成器

一般脚手架工具都是全局安装,使用-g参数即可全局安装,使用时无需使用npx命令前缀

首先使用npm install koa-generator -D命令本地安装脚手架工具,使用npx koa2 项目名 创建项目,默认模板引擎是jade,使用help参数进行查看其他模板引擎的支持,创建出的目录结构

文件或目录名 描述
bin/www 是项目的入口文件,仅提供http服务器对象用于启动项目
app.js 各种中间件注册,比如:路由,静态资源,错误,404等
routes 路由目录
views 视图模板目录
public 公共静态资源目录

app.js文件中其他中间件解释

const json = require('koa-json')
const onerror = require('koa-onerror')
const logger = require('koa-logger')
onerror(app)	//浏览器显示错误信息,与模板引擎无关
app.use(json())	//返回的json格式更加好看
app.use(logger())	//console.log()输出内容增加附加信息

www文件中其他中间件解释

与express中的一致,具体参考express的解释

package.json中其他包解释

  • koa-convert:用于将koa1包中使用的Generator函数转换成Koa2中的async函数,对于高版本的nodejs是不需要的,可以删除
此作者没有提供个人介绍
最后更新于 2020-07-04