Node(三)koa一篇搞定

目录

一. Koa的使用

1.1. koa的基本使用

1.2. koa中间件ctx参数

1.3. 手动区分路径和方法

1.4. 创建Koa的路由@koa/router

1.5. koa中五种数据解析方法

1.6. koa中文件上传的处理

二. Koa的其他用法

2.1. 静态资源服务器

2.2. 返回响应的信息

2.3. 错误处理的方案

三. koa和express的区别

3.1. 架构上的区别

3.2. 执行异步代码区别

3.3. koa的洋葱模型


一. Koa的使用

1.1. koa的基本使用

const Koa=require('koa')
​
// 创建app
const app=new Koa()
​
// 注册中间件
// koa的中间件有两个参数:ctx,next
app.use((ctx,next)=>{
  console.log('匹配到koa的中间件')
​
  // 返回数据
  ctx.body='哈哈哈哈'
})
​
​
// 启动服务器
app.listen(6000,()=>{
  console.log('koa服务器启动')
})

1.2. koa中间件ctx参数

const Koa=require('koa')
​
// 创建app
const app=new Koa()
​
// 注册中间件
app.use((ctx,next)=>{
// 1.请求的对象
console.log(ctx.request) //koa封装的对象
console.log(ctx.req)//node封装的对象
​
// 2.响应对象
console.log(ctx.response)//koa封装的对象
console.log(ctx.res)//node封装的对象
ctx.body='请求成功'
})
​
​
// 启动服务器
app.listen(6000,()=>{
  console.log('koa服务器启动')
})

1.3. 手动区分路径和方法

// 注册中间件
// 在koa中自己区分路径和方式非常麻烦
// 一般直接用路由区分
app.use((ctx,next)=>{
  if(ctx.path==='/user'){
    if(ctx.method==='GET'){
          ctx.body='user page'
    }
  }else if(ctx.path==='/login'){
    if(ctx.method==='POST'){
      ctx.body='login success'
    }
  }
})
 

1.4. 创建Koa的路由@koa/router

const KoaRouter=require('@koa/router')
// 1.创建路由对象
const userRouter=new KoaRouter({prefix:'/users'})
​
// 2.在路由中注册中间件:path/method
userRouter.get("/",(ctx,next)=>{
  ctx.body='user list data'
})
​
userRouter.get("/:id",(ctx,next)=>{
  ctx.body='获取某一个用户'+ctx.params.id
})
module.exports=userRouter


const Koa=require('koa')
const userRouter=require('./router/userRouter')
// 创建app
const app=new Koa()
​
// 注册中间件
// 使用路由
app.use(userRouter.routes())
​
// 启动服务器
app.listen(6000,()=>{
  console.log('koa服务器启动')
})

1.5. koa中五种数据解析方法

重点是两个第三方解析库koa-bodyparser、@koa/multer

const Koa=require('koa')
const KoaRouter=require('@koa/router')
// 这个东西解析不了表单数据
const bodyParse=require('koa-bodyparser')
// 用这个解析表单数据
const multer=require('@koa/multer')
// 创建app
const app=new Koa()
​
// 使用第三方中间件解析body数据
app.use(bodyParse())
const formMulter=multer()
​
// 注册路由对象
const userRouter=new KoaRouter({prefix:'/users'})
​
​
// 注册中间件
// 1.params
userRouter.get('/:id',(ctx,next)=>{
  const id=ctx.params.id
  ctx.body='user list'+id
})
// 2.query
userRouter.get('/',(ctx,next)=>{
  console.log('1111')
  const query=ctx.query
  // console.log(query)
  ctx.body="用户的query数据"+JSON.stringify(query)
})
​
// 3.post/json数据
userRouter.post('/json',(ctx,next)=>{
    console.log(ctx.request.body)
    ctx.body='用户传来的josn数据'
})
​
// 4.post/urlrncoded
userRouter.post('/urlencoded',(ctx,next)=>{
  console.log(ctx.request.body)
  ctx.body='用户传来的urlencoded数据'
})
// 5.post/formdata
userRouter.post('/formdata',formMulter.any(),(ctx,next)=>{
  console.log(ctx.request.body)
  ctx.body='用户传来的formdata数据'
})
// 使用路由
app.use(userRouter.routes())
app.use(userRouter.allowedMethods())
// 启动服务器
app.listen(6000,()=>{
  console.log('koa服务器启动')
})

1.6. koa中文件上传的处理

  • multer @koa/multer

    const Koa=require('koa')
    const KoaRouter=require('@koa/router')
    const multer=require('@koa/multer')
    ​
    // 创建app对象
    const app=new Koa()
    ​
    // 解析上传的文件
    ​
    // 这种方式没有文件后缀
    // const upload=multer({
    //   dest:'./uploads'
    // })
    ​
    // 这种方式有文件后缀
    const upload=multer({
      storage:multer.diskStorage({
        destination(req,file,cb){
          cb(null,'./uploads')
        },
        filename(req,file,cb){
          cb(null,Date.now()+'_'+file.originalname)
        }
      })
    })
    //注册路由对象
    const uploadRouter=new KoaRouter({prefix:'/upload'})
    uploadRouter.post('/avatar',upload.single('avatar'),(ctx,next)=>{
      // 文件的详细信息都在这里面
      console.log(ctx.request.file)
      ctx.body='文件上传成功'
    })
    ​
    uploadRouter.post('/photos',upload.any('/photos'),(ctx,next)=>{
      // 文件的详细信息
      console.log(ctx.request.files)
      ctx.body='文件s上传成功'
    })
    // 使用路由
    app.use(uploadRouter.routes())
    app.use(uploadRouter.allowedMethods())
    ​
    // 启动服务器
    app.listen(6000,()=>{
      console.log('koa服务器启动')
    })

二. Koa的其他用法

2.1. 静态资源服务器

const Koa=require('koa')
const static=require('koa-static')
​
const app=new Koa()
​
app.use(static('./uploads'))
app.listen(8000,()=>{
  console.log('koa服务器启动成功')
})

2.2. 返回响应的信息

const Koa=require('koa')
const koaRouter=require('@koa/router')
const fs=require('fs')
const userRouter=new koaRouter({prefix:'/user'})
const app=new Koa()
​
userRouter.get('/',(ctx,next)=>{
  // 1.body类型是字符串
  // ctx.body='请求成功'
​
  // 2.body类型是Buffer
  // ctx.body=Buffer.from('你好')
​
  // 3.body类型是Stream
  // const readStream=fs.createReadStream('./uploads/1737376996081_abstract.png')
  // ctx.type='image/jpeg'
  // ctx.body=readStream
​
  //4. body类型是对象或者字符串
  // ctx.body={
  //   code:0,
  //   data:[
  //     {id:111,name:'iphone'},
  //     {id:112,name:"xiaomi"}
  //   ]
  // }
​
  // 5.body类型是null 自动设置http status的值为204
  ctx.body=null
})
​
app.use(userRouter.routes())
app.use(userRouter.allowedMethods())
app.listen(8000,()=>{
  console.log('koa服务器启动成功')
})

2.3. 错误处理的方案

const Koa=require('koa')
const koaRouter=require('@koa/router')
const fs=require('fs')
const userRouter=new koaRouter({prefix:'/user'})
const app=new Koa()
​
userRouter.get('/',(ctx,next)=>{
  const isAuth=false
  if(isAuth){
    ctx.body='访问成功'
  }else{
    
    //触发事件 传ctx是为了让那个处理错误的中间件能够返回错误
    ctx.app.emit('error',-1003,ctx)
  }
})
// 监听事件
app.on('error',(code,ctx)=>{
  const errCode=code
  let message='未知错误'
  switch(errCode){
    case -1001:
      message='账号或密码错误'
      break
    case -1002:
      message='内容为空'
      break
    case -1003:
      message='未授权'
      break
  }
  ctx.body={
    code:errCode,
    message
  }
})
​
app.use(userRouter.routes())
app.use(userRouter.allowedMethods())
app.listen(8000,()=>{
  console.log('koa服务器启动成功')
})

三. koa和express的区别

3.1. 架构上的区别

3.2. 执行异步代码区别

express执行异步代码

const express=require('express')
const { default: axios } = require('axios')
​
// 创建app对象
const app=express()
​
​
// 编写中间件
app.use((req,res,next)=>{
  console.log('koa middleware01')
  req.msg='aaa'
   next()
​
})
​
app.use((req,res,next)=>{
  console.log('koa middleware02')
  req.msg+='bbb'
  next()
})
​
app.use(async (req,res,next)=>{
  console.log('koa middleware03')
  const resData=await axios.get('http://123.207.32.32:8000/home/multidata')
  req.msg+=resData.data.data.banner.list[0].title
  // express 异步代码只能在这里返回结果 像koa那样在next函数前await没有用 因为express的next函数返回的是void
  // koa的next函数返回的是Promise
  res.end(req.msg)
})
​
// 启动服务器
app.listen(8000,()=>{
  console.log('express服务器启动成功')
})

koa执行异步代码

const { default: axios } = require('axios')
const Koa=require('koa')
​
// 创建服务器
const app=new Koa()
app.use(async(ctx,next)=>{
  console.log('koa middleware01')
  ctx.msg='aaa'
  // 如果执行的下一个中间件是一个异步函数,那么next默认不会等到中间件的结果就执行下一步操作
  // 如果我们希望等到下一个异步函数的结果,那么需要在next函数前面加上await
  await next()
  // 返回结果
  ctx.body=ctx.msg
})
​
app.use(async(ctx,next)=>{
  console.log('koa middleware02')
  ctx.msg+='bbb'
  await next()
})
​
app.use(async (ctx,next)=>{
  console.log('koa middleware03')
  const res=await axios.get('http://123.207.32.32:8000/home/multidata')
  ctx.msg+=res.data.data.banner.list[0].title
})
// 启动服务器
app.listen(8000,()=>{
  console.log('koa服务器启动成功')
​
})

3.3. koa的洋葱模型

就是中间件根据碰到next就去下一个中间件执行 当执行完最后一个中间件再回来执行倒数第二个中间件next函数后面的代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值