一、koa安装与hello world示例:
koa需要node v7.6.0以上(因为需要ES6)
npm install koa --save
习惯性加上save,不加也可以。
koa的hello world示例
const Koa = require('koa');
const app = new Koa();
app.use(async(ctx)=>{
ctx.body = 'hello koa!';
})
app.listen(3000);
这个示例很简单,从node_modules中导入Koa类,然后实例化给app,通过app.use(中间件处理函数)来触发接受请求(每当有请求的时候就会按编写顺序和next堆栈方式触发这些所有的中间件函数),通过koa语法糖创建监听端口.
ctx.body即是我们显示在网页上的内容。
二、next函数与中间件调用顺序
官网的表述:
Koa 的中间件通过一种更加传统(您也许会很熟悉)的方式进行级联,摒弃了以往 node 频繁的回调函数造成的复杂代码逻辑。 然而,使用异步函数,我们可以实现"真正" 的中间件。与之不同,当执行到 yield next 语句时,Koa 暂停了该中间件,继续执行下一个符合请求的中间件(‘downstrem’),然后控制权再逐级返回给上层中间件(‘upstream’)。
下面的例子在页面中返回 “Hello World”,然而当请求开始时,请求先经过 x-response-time 和 logging 中间件,并记录中间件执行起始时间。 然后将控制权交给 reponse 中间件。当一个中间件调用next()函数时,函数挂起并控件传递给定义的下一个中间件。在没有更多的中间件执行下游之后,堆栈将退出,并且每个中间件被恢复以执行其上游行为。
// 中间件函数参数 第一个context上下文对象 第二个next函数,用于控制koa的执行顺序
// 接下来我们编写三个中间件使得koa能够反馈响应并打印到控制台上
// 打印请求方式和请求地址
const Koa = require('koa');
const app = new Koa();
// 大致意义就是堆栈类似的调用方式:x-response-time -> logger -> response ->logger ->x-response-time
app.use(async (ctx, next) => {
const start = Date.now();
console.log("x-response-time was used at 1")
await next();
console.log("x-response-time was used at 2")
const ms = Date.now() - start;
// 这句话的意义是设置返回头 response headers
ctx.set('X-Response-Time', `${
ms}ms`);
});
// logger
app.use(async (ctx, next) => {
const start = Date.now();
console.log("logger was used at 1")
await next();
console.log("logger was used at 2")
const ms = Date.now() - start;
console.log(`${
ctx.method} ${
ctx.url} - ${
ms}`);
});
// response
app.use(async ctx => {
console.log("response was used at 1")
ctx.body = 'Hello World';
});
app.listen(3000);
打印结果:
x-response-time was used at 1
logger was used at 1
response was used at 1
logger was used at 2
GET / - 12
x-response-time was used at 2
大致意义就是堆栈类似的调用方式:x-response-time,next之前的内容 -> logger,next之前的内容 -> response,无next,全部调用 ->logger,next之后的内容 ->x-response-time,next之后的内容->结束
三、request对象和参数的获取
get请求:
我们可以通过ctx.request
属性获取统一的request对象,获取其中url/query的内容
const Koa = require("koa");
const app = new Koa();
app.use(async (ctx) => {
let url = ctx.url;
let request = ctx.request;
// query返回的是格式化好的参数对象,querystring则是请求字符串,