目录
一. 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函数后面的代码