Koa2:CTX上下文对象、模块路由、父子路由的模块化、路由传值以及配置静态资源目录

官网定义:
Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。

需要注意的是,在引入Koa的时候定义的变量建议首字母大写,因为引入进来的Koa是一个构造函数,与之对比express的小写不同,express引入进来的是一个方法。

  • Koa的安装
    npm install koa

  • Koa的上下文对象
    Koa与express在此处也是有不同的地方的,Koa的参数中有一个ctx对象,全称是context(上下文对象),该对象中有很多请求对象和响应对象的属性,而express则是request和response对象。

所有的context对象中存在的属性

{
  "request": {
    "method": "GET",
    "url": "/",
    "header": {
      "host": "localhost:3000",
      "connection": "keep-alive",
      "cache-control": "max-age=0",
      "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"99\", \"Google Chrome\";v=\"99\"",
      "sec-ch-ua-mobile": "?0",
      "sec-ch-ua-platform": "\"Windows\"",
      "upgrade-insecure-requests": "1",
      "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36",
      "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
      "sec-fetch-site": "none",
      "sec-fetch-mode": "navigate",
      "sec-fetch-user": "?1",
      "sec-fetch-dest": "document",
      "accept-encoding": "gzip, deflate, br",
      "accept-language": "zh-CN,zh;q=0.9",
      "cookie": "iuuid=4A6BA4B09FA911EBA94155995BDE1980F51D01EB2506461C9D1BF46E6BD25428; ci=70%2C%E9%95%BF%E6%B2%99; Idea-27a01726=250b0cc9-2f91-456f-83fd-66b3dff3918e; Webstorm-c53c985b=b15edf29-a690-4fb1-a5bd-88d2878d8a56; SECKEY_ABVK=jMUoQpA+5zzQgKXv6AnOLZbxz5WrzCuZXMJxC5QJC/E%3D; BMAP_SECKEY=AOPUfxtQBFx_D_6foKit2bazjnrEcFzzNmJl9eJeOnrWvmntrgnn-iMB2UQeFQupVAafGctwrk9ix-Am92bVty4JxMv4RJesowbLSnJfHcIzQ2lPgHISfc8UJAyv17ks_1W8cPtpHrVSQwwT9ZY-vbaQ1Ic88ykE0s8g3-caMyOnt_UR854OuvjWPqRQ-CKS"
    }
  },
  "response": {
    "status": 200,
    "message": "OK",
    "header": {
      "content-type": "application/json; charset=utf-8"
    }
  },
  "app": {
    "subdomainOffset": 2,
    "proxy": false,
    "env": "development"
  },
  "originalUrl": "/",
  "req": "<original node req>",
  "res": "<original node res>",
  "socket": "<original node socket>"
}

代码示例:

const Koa = require('koa');

const app = new Koa;

/**
 * ctx 上下文对象(也就是说当前的作用环境)
 * ctx : {
 *     response 响应对象
 *     request 请求对象
 *     body 指的就是response.body, 向前端发送数据
 *     ...
 *     其他的属性很多是请求对象和响应对象中比较常用的属性 
 * }
 */
app.use((ctx , next) => {
    ctx.response.body = 'hello';
})

app.listen(3000, () => console.log('http://localhost:3000'))
  • Koa的app应用程序挂载到其他服务器上
    如果使用Koa的时候不想在Koa代码内去挂载端口,那么可以导出一个app,然后通过Koa自带的app.callback()回调函数去执行,挂载至其他外部服务器上去。
// 认识koa与上下文对象
const Koa = require('koa');

const app = new Koa;

/**
 * Koa的callback()函数
 * 可以将当前app应用程序挂载到其他服务器上
 */
app.use((ctx, next) => {
    ctx.body = `<h1>首页状态</h1>`
})

// 导出app
module.exports = app;

然后我们通过原生node的HTTP内置模块监听一个5000端口写一个服务器,再将导出的app应用程序挂载到这个端口上来

const http = require('http');

const app = require('./index.js');

http.createServer(
    app.callback()
).listen(5000, () => console.log('http://localhost:5000'))
  • 错误程序处理
    通过使用app.on('error', (err, ctx) => { })去监听错误信息
const Koa = require('koa');

const app = new Koa;

app.use((ctx, next) => {
    throw new Error('程序抛异常')
    ctx.body = `<h1>首页状态</h1>`
})

/**
 * error 错误处理
 */
app.on('error', (err, ctx) => {
    console.log(err)
})

app.listen(3000, () => console.log('http://localhost:3000'))
  • 模块路由
    路由是一个URL和一个特定的HTTP方法组成,涉及到应用如何响应客户端对某个网站节点的访问
    也就是说:路由即根据不同的URL地址,加载不同的页面实现不同的功能。
    Koa路由和Express的路由有区别的,在Exprss中直接引入Express就可以配置路由了,但是在Koa中我们需要安装对应的koa-router来实现
    安装koa-router
    npm install --save koa-router

创建并使用路由

共分为4步骤:
第一步:导入koa-router
第二步:创建实例化对象
第三步:生成路由
第四步:将路由挂载到应用程序

const Koa = require('koa');

const app = new Koa;
// 第一步:导入koa-router
const Router = require('koa-router')

// 第二步:创建实例化对象
const router = new Router;

// 第三步:生成路由
router.get('/', (ctx, next) => {
    ctx.body = '首页'
})

// 第四步:将路由挂载到应用程序
app.use(router.routes())
app.use(router.allowedMethods())

app.listen(3000, () => console.log('http://localhost:3000'))

父子路由的模块化使用
创建一个routes目录,下面分别新建一个student.js和teacher.js用于存放学生路由和教师路由文件

// 学生的路由模块
const Koa = require('koa');

const app = new Koa;

const Router = require('koa-router');

const studentRouter = new Router;

studentRouter.get('/student', (ctx, next) => {
    ctx.body = '学生首页'
})

studentRouter.get('/student/add', (ctx, next) => {
    ctx.body = '新增学生首页'
})

studentRouter.get('/student/delete', (ctx, next) => {
    ctx.body = '删除学生首页'
})

studentRouter.get('/student/update', (ctx, next) => {
    ctx.body = '更新学生首页'
})

studentRouter.get('/student/serach', (ctx, next) => {
    ctx.body = '查询学生首页'
})

module.exports = studentRouter;
// 老师的路由模块
const Koa = require('koa');

const app = new Koa;

const Router = require('koa-router');

const teacherRouter = new Router;

teacherRouter.get('/teacher', (ctx, next) => {
    ctx.body = '老师首页'
})

teacherRouter.get('/teacher/add', (ctx, next) => {
    ctx.body = '新增老师首页'
})

teacherRouter.get('/teacher/delete', (ctx, next) => {
    ctx.body = '删除老师首页'
})

teacherRouter.get('/teacher/update', (ctx, next) => {
    ctx.body = '更新老师首页'
})

teacherRouter.get('/teacher/serach', (ctx, next) => {
    ctx.body = '查询老师首页'
})

module.exports = teacherRouter;

然后我们在主应用程序只需要去引入这两个路由模块即可

const Koa = require('koa');

const app = new Koa;

// 引入学生路由模块
const studentRouter = require('./routes/student.js')
app.use(studentRouter.routes(), studentRouter.allowedMethods())

// 引入教师路由模块
const teacherRouter = require('./routes/teacher.js')
app.use(teacherRouter.routes(), teacherRouter.allowedMethods())


app.listen(3000, () => console.log('http://localhost:3000'))
图1.png
  • 路由传值
    Koa2中get传值通过request接收,接收的方法有两种:query和querystring

1、query: 返回的是格式化好的参数对象
2、querystring: 返回的是请求字符串

router.get('/', async (ctx, next) => {
  console.log(ctx.query) // 一般使用这个
  console.log(ctx.querystring)
  console.log(ctx.request.query)
  console.log(ctx.request.querystring)
})
  • 静态资源目录static中间件
    其实router以及static对于koa来说都算是一个内置的中间件
app.use(static())
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容