博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Koa2 入门实践
阅读量:4085 次
发布时间:2019-05-25

本文共 7619 字,大约阅读时间需要 25 分钟。

第一个例子:启动

初始化项目,安装环境

# -y 就是不想自己逐条配置,直接全部使用默认配置npm init -y# 安装 koa 并写入 package.json 中npm i koa --save# 好的代码规范还是必要的npm i standard --save-dev# 安装 nodemon 用于开发环境快速自动重启npm i -g nodemon

配置开发选项

这个时候我们就可以用到 npm script 了,避免重复输入命令

# package.json 中的 scripts 中添加# 正常启动服务"start": "node index.js",# 启动开发环境,保存修改内容后自动重启"dev": "NODE_ENV=develpment nodemon index.js"
  • 编写 index.js

这个时候我们新建一个文件叫 index.js 并编辑它

// index.js// 引入 koaconst Koa = require('koa')// 新建 koa 实例const app = new Koa()app.use(async (ctx) => { ctx.body = JSON.stringify(ctx) })// 监听 5820 端口,服务启动成功输出内容app.listen(5820, () => { console.log('APP LISTEN PORT 5820') })

然后我们在项目下打开终端,输入 npm run dev 就可以启动服务的开发模式了,这个时候可以看到控制台输出了 APP LISTEN PORT 5820,同时我们打开浏览器并访问 localhost:5820 ,就可以看到当前访问的上下文信息了

这是最简单的例子,同时也是最重要的,标志了你已可以正式启动 Koa 服务了

GET 请求的参数接收

写一个最简单的例子

// 引入 koaconst Koa = require('koa')// 新建 koa 实例const app = new Koa()app.use(async (ctx) => {  ctx.body = {    url: ctx.url,    params: ctx.request.query,    param_string: ctx.request.querystring,    ctx_params: ctx.query,    ctx_params_string: ctx.querystring  }})// 监听 5820 端口,服务启动成功输出内容app.listen(5820, () => { console.log('APP LISTEN PORT 5820') })

这个时候,我们在浏览器提交一个请求,使用get访问 localhost:5820?hello=world&pika=qiu

这个时候我们就可以查看内容了

从这里可以看出

获取在 koa 中 GET 的参数方式有两种:query和querystring。同时我们可以看出,在可以从 request 中接收 GET 请求和直接从上下文中接收 GET 请求都是可以的。

  • query:返回的是的参数对象。
  • querystring:返回的是请求字符串。

POST 请求的参数接收

koa 并不带 POST 请求的解析,这个时候,我们就要自己编写 POST 请求的解析函数了

function parseParams (ctx) {  return new Promise((resolve, reject) => {    try {      let paramsdata = ''      ctx.req.on('data', (data) => {        paramsdata += data      })      ctx.req.addListener('end', function () {        resolve(parseQueryStr(paramsdata))      })    } catch (error) {      reject(error)    }  })}function parseQueryStr (queryStr) {  let queryData = {}  let queryStrList = queryStr.split('&')  for (let [index, queryStr] of queryStrList.entries()) {    let itemList = queryStr.split('=')    queryData[itemList[0]] = decodeURIComponent(itemList[1])  }  return queryData}

使用的时候就可以这么使用

app.use(async (ctx) => {  let params = await parseParams(ctx)  ctx.body = {    method: ctx.method,    url: ctx.url,    params  }})

这个时候,我们可以使用 POSTMAN 来模拟一下 POST 请求的发送,我们可以发现参数已经被成功解析了

koa-bodyparser 中间件

当然 POST 请求这么常见的需求是一定有造好的轮子的,这个时候我们就可以使用 koa-bodyparser 来进行参数的解析了

安装依赖

npm i koa-bodyparser --save
  • 引入并使用
// 引入 koaconst Koa = require('koa')// 引入 koa-bodyparserconst KoaBodyparser = require('koa-bodyparser')// 新建 koa 实例const app = new Koa()// 使用中间件app.use(KoaBodyparser())app.use(async (ctx) => {  ctx.body = {    method: ctx.method,    url: ctx.url,    params: ctx.request.body  }})// 监听 5820 端口,服务启动成功输出内容app.listen(5820, () => { console.log('APP LISTEN PORT 5820') })

然后我们使用 POSTMAN 模拟一下请求就可以看出,这里我们直接使用 ctx.request.body 就可以取到格式化后的参数对象了

koa 原生路由

先编写一个简单的中间件

// 因为使用了 fs 模块,所以我们要引入const fs = require('fs')// 先写好对应的文件,然后写一个读取文件内容的函数function readfile (params) {  return new Promise((resolve, reject) => {    fs.readFile(`./route/${params}.html`, 'binary', (err, data) => {      if (err) {        reject(err)      } else {        resolve(data)      }    })  })}
// 再编写路由配置async function route (url) {  let page = ''  switch (url) {    case '/index':      page = 'index'      break    case '/page':      page = 'page'      break    case '/user':      page = 'user'      break    default: page = '/404'      break  }  let html = await readfile(page)  return html}
// 就可以这么使用了app.use(async (ctx) => {  let html = await route(ctx.url)  ctx.body = html})

koa-router中间件

当然,常用的东西肯定是有中间件的,这个时候我们就可以祭出 koa-router

安装 koa-router

npm i koa-router --save
  • 基础案例
// 引入 koaconst Koa = require('koa')// 引入 koa-routerconst KoaRouter = require('koa-router')// 实例化一个 koa 对象const app = new Koa()// 实例化一个 router 对象let route = new KoaRouter()// 表示接收 get 请求,接收 url 为 /// 其中 next 指的是下一个中间件,可以在代码中使用 await next() 来提前执行route.get('/', (ctx, next) => {  ctx.body = 'Hello get'})// 表示接收 post 请求route.post('/test', (ctx, next) => {  ctx.body = 'hello post'})// 表示接收全部请求route.all('/all', (ctx, next) => {  ctx.body = 'hello all'})// 装载路由,并只允许指定方法访问app.use(route.routes()).use(route.allowedMethods())// 监听 5820 端口,服务启动成功输出内容app.listen(5820, () => { console.log('APP LISTEN PORT 5820') })

层级案例

当然,日常工作中的路由不可能这么简单,这个时候我们就需要使用多层次的路由的,下面看案例

先简单创建一下目录并路由文件

mkdir routetouch route1.js route2.js
// route1.jslet KoaRouter = require('koa-router')let route = new KoaRouter()route.get('/test1', (ctx, next) => {  ctx.body = 'route1 test1'})route.get('/test2', (ctx, next) => {  ctx.body = 'route1 test2'})route.get('/test3', (ctx, next) => {  ctx.body = 'route1 test3'})module.exports = route
// route2.jslet KoaRouter = require('koa-router')let route = new KoaRouter()route.get('/test1', (ctx, next) => {  ctx.body = 'route2 test1'})route.get('/test2', (ctx, next) => {  ctx.body = 'route2 test2'})route.get('/test3', (ctx, next) => {  ctx.body = 'route2 test3'})module.exports = route
// 根目录下的 server.js// 引入 koa,路由const Koa = require('koa')let KoaRouter = require('koa-router')// 实例化一个 koa 对象const app = new Koa()// 创建一个全局的父路由,子路由要全部挂载在父路由下let fatherRoute = new KoaRouter()// 引入子路由const route1 = require('./route/route1')const route2 = require('./route/route2')// 装载路由,并只允许指定方法访问fatherRoute.use('/route1', route1.routes(), route1.allowedMethods())fatherRoute.use('/route2', route2.routes(), route2.allowedMethods())// Koa 装载父路由app.use(fatherRoute.routes()).use(fatherRoute.allowedMethods())// 监听 5820 端口,服务启动成功输出内容app.listen(5820, () => { console.log('APP LISTEN PORT 5820') })
  • 这个时候我们就可以启动,然后访问 localhost:5820/route1/test1

localhost:5820/route2/test3 来查看一下效果

koa 中使用cookie

最简单的 key-value 形式设置与获取

// 引入 koaconst Koa = require('koa')// 引入 koa-routerconst KoaRouter = require('koa-router')// 实例化一个 koa 对象const app = new Koa()// 实例化一个 router 对象let route = new KoaRouter()// 最简单的 key-value 形式,可以直接使用上下文对象提供的 cookie 对象进行操作route.get('/', (ctx, next) => {  ctx.cookies.set(    'TESTCOOKIE', 'LOVEWZJ'.repeat(5)  )  ctx.body = 'SET COOKIE OK'})// 获取 cookieroute.get('/test', (ctx, next) => {  ctx.body = `GET COOKIE IS ${ctx.cookies.get('TESTCOOKIE')}`})// 装载路由,并只允许指定方法访问app.use(route.routes()).use(route.allowedMethods())// 监听 5820 端口,服务启动成功输出内容app.listen(5820, () => { console.log('APP LISTEN PORT 5820') })
// 复杂的 key-value-options 形式route.get('/', (ctx, next) => {  ctx.cookies.set(    'TESTCOOKIE', 'LOVEWZJ', {      maxAge: 1000 * 60 * 60 * 24,      expires: new Date('2018-12-31')    }  )  ctx.body = `SET COOKIE OK ${new Date().toLocaleTimeString()}`})
  • 配置项
名称 含义 示例
path cookie 的路径 默认 /
domain cookie 的域 *.baidu.com
expires cookie 有效期时间 new Date(‘2018-12-31’)
maxAge cookie 最大存活时间 1000 * 60 * 60 * 24
httpOnly 是否只能通过 HTTP 协议发送 true|false
signed 是否要做签名 true|false
secure 通过什么协议发送 cookie false 表示 cookie 通过 HTTP 协议发送,true 表示 cookie 通过 HTTPS 发送
overwirte 是否允许重写 true|false

koa-static 中间件

对于一些静态的资源,比如图片,CSS文件,JS文件,HTML文件等资源,我们可以直接使用 koa-static 中间件进行处理。

安装依赖

npm i kao-static --save
  •  

应用

注意:这里是把所有的静态资源放在 static 目录下

// 引入 koaconst Koa = require('koa')// 引入 path 模块const path = require('path')// 引入 koa-static 中间件const KoaStatic = require('koa-static')// 实例化一个 koa 对象const app = new Koa()// 装载静态资源中间件app.use(KoaStatic(  path.join(__dirname, './static')))// 监听 5820 端口,服务启动成功输出内容app.listen(5820, () => { console.log('APP LISTEN PORT 5820') })

koa 中间件

app.use() 的功能实际上就是把里面的函数加入到回调函数执行列表中,下面我们写一个简单的例子来看一下

// 引入 koaconst Koa = require('koa')// 实例化一个 koaconst app = new Koa()app.use(log)app.use(async (ctx) => { ctx.body = ctx.url })// 我们写的异步程序async function log (ctx, next) {  ctx.url = 'I CAN CHANGE CTX URL'  await next()}// 监听 5820 端口,服务启动成功输出内容app.listen(5820, () => { console.log('APP LISTEN PORT 5820') })

转载

你可能感兴趣的文章
【JAVA数据结构】双向链表
查看>>
【JAVA数据结构】先进先出队列
查看>>
String类的intern方法随笔
查看>>
【泛型】一个简易的对象间转换的工具类(DO转VO)
查看>>
1.随机函数,计算机运行的基石
查看>>
MouseEvent的e.stageX是Number型,可见as3作者的考虑
查看>>
在mc中直接加aswing组件,该组件还需最后用validate()方法
查看>>
移植Vim配色方案到Eclipse
查看>>
从超链接调用ActionScript
查看>>
谈谈加密和混淆吧[转]
查看>>
TCP的几个状态对于我们分析所起的作用SYN, FIN, ACK, PSH,
查看>>
网络游戏客户端的日志输出
查看>>
关于按钮的mouseOver和rollOver
查看>>
《多线程服务器的适用场合》例释与答疑
查看>>
Netty框架
查看>>
Socket经验记录
查看>>
对RTMP视频流进行BitmapData.draw()出错的解决办法
查看>>
FMS 客户端带宽计算、带宽限制
查看>>
在线视频聊天(客服)系统开发那点事儿
查看>>
SecurityError Error 2148 SWF 不能访问本地资源
查看>>