koa中间件

263 阅读3分钟

koa中匹配路由之后完成的一系列操作


中间件的作用

1、执行任何代码;
2、修改请求和响应请求;
3、终结请求/响应循环;
4、调用堆栈中的下一个中间件。

中间件的划分

1、应用级中间件;
2、路由级中间件;
3、错误处理中间件;
4、第三方中间件。

拓展:

与Express不相同的是,Koa的中间件不会因为代码位置而存在先后执行的问题,无论在什么位置,代码会优先执行中间件,再去匹配路由,执行路由方法。


1、应用级中间件

匹配路由之前或者匹配路由之时执行操作

let Koa = require('koa')
let router = require('koa-router')()
let app = new Koa()

// 任何路由执行之前都会运行此中间件,运行完毕以后结束执行
app.use(async (ctx) => {
  ctx.body = '这是一个中间件'
})

router.get('/', async (ctx) => {
  ctx.body = 'Main Page'
})
app
  .use(router.routes())
  .use(router.allowedMethods())
app.listen(3000)

程序在运行的时候,无论什么请求路径都会优先执行中间件,因为中间件无 next() 方法,所以上下文的ctx.body返回给页面值后,不会向下执行。

如果需要执行完中间件以后继续向下执行匹配行为,需要加入next参数与next方法

  app.use(async (ctx, next) => {
    ctx.body = '这是一个中间件'
    // 匹配当前路由以后继续向下匹配
    await next()
  })

  router.get('/', async (ctx) => {
    ctx.body = 'Main Page'
  })

结果,页面打印

Main Page

所以不写next,路由一开始被中间件匹配以后就不会向下执行。

2、路由级中间件

在路由执行完毕以后不会结束代码,会通过next方法继续执行到下一个匹配的路有方法

router.get('/', async (ctx, next) => {
  console.log('Server print words: Mayumi is my WiFi!')
  await next()
})
// 上一个路由执行,但是借由next方法所以不会结束,会继续执行代码到下一步无next方法的路由上去
router.get('/', async (ctx) => {
  ctx.body = 'Mayumi is a sup player of INTZs LOL branch'
})

在url为 localhost:3000 的时候,Server terminal显示结果:

Server print words: Mayumi is my WiFi!

chrome显示结果:

Mayumi is a sup player of INTZs LOL branch

3、错误处理中间件

错误处理中间件,其实是根据context的状态属性来分配执行操作的一个中间件,根据koa的执行流程而来。

app.use(async (ctx, next) => {
  console.log('错误处理中间件')
  await next()
  console.log(ctx.status)
  if (ctx.status === 404) {
    ctx.status = 404
    ctx.body = '404 - Not Found'
  }
})
router.get('/', async (ctx, next) => {
  console.log('Server print words: Mayumi is my WiFi!')
  await next()
})
// 上一个路由执行,但是借由next方法所以不会结束,会继续执行代码到下一步无next方法的路由上去
router.get('/', async (ctx) => {
  ctx.body = 'Mayumi is a sup player of INTZs LOL branch'
})

sever开启以后,获取到请求,首先执行中间件,执行到 await next() 会直接去寻找相匹配的路由执行,执行完毕以后会返回到 next() 调用方法的地方,继续执行下面的代码。

url: localhost:3000

server terminal:

错误处理中间件
Server print words: Mayumi is my WiFi!
200

chrome:

Mayumi is a sup player of INTZs LOL branch

url: localhost:3000/xxx

server terminal:

错误处理中间件
404

chrome:

404 - Not Found

拓展

next() 可以理解是,优先执行参数带next的路由方法,执行完毕以后再返回到调用 next() 方法的地方,继续执行后面的代码。类似俄罗斯套娃原理, next() 方法就是开启箱子的事件,套娃是匹配到的代码的执行内容,执行完毕以后,依次关闭箱子,并执行关闭箱子以后父亲箱子中的套娃代码。