• 【node进阶】深度解析Koa框架---路由|静态资源|获取请求参数


    ✅ 作者简介:一名普通本科大三的学生,致力于提高前端开发能力
    ✨ 个人主页:前端小白在前进的主页
    🔥 系列专栏 : node.js学习专栏
    ⭐️ 个人社区 : 个人交流社区
    🍀 学习格言: ☀️ 打不倒你的会使你更强!☀️
    💯 刷题网站:这段时间有许多的小伙伴在问有没有什么好的刷题网站,博主在这里给大家推荐一款刷题网站:👉点击访问牛客网👈牛客网支持多种编程语言的学习,各大互联网大厂面试真题,从基础到拔高,快来体验一下吧!


    在这里插入图片描述


    🔥前言

    上文中我们已经对koa框架有了一个简单的理解,并且也懂得了koa框架的优点和不足,同时在koa框架中路由的使用、静态资源的访问、获取请求的参数都有了一定的改变,该文章将讲述这三点!

    路由

    Koa框架中与Express的区别在这里也有一个很大的展现。在Express框架中路由模块是内置模块,而在Koa中,路由模块非内置模块,需要单独的去下载。

    koa路由的基本使用

    安装Koa框架路由模块(koa-router):

    npm i koa-router
    
    • 1

    安装成功后进行引用:

    const Koa = require("koa")
    const Router = require("koa-router")
    
    const app = new Koa()
    const router = new Router()
    
    router.post("/list",(ctx)=>{
        ctx.body=["111","222","333"]
    })
    app.use(router.routes()).use(router.allowedMethods())
    app.listen(3000)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    通过以上的代码可以看出来,在koa框架中需要用到关键字new来实例化一个对象,才能进行调用。在应用级中间件中有一个方法router.routes(),它的作用是将路由对象中所有的路由模块都挂载成为应用级中间件


    router.allowedMethods作用

    在上方的代码中大家还看到了不认识的方法router.allowedMethods(),router.allowedMethods()中间件,主要用于 405 Method Not Allowed 这个状态码相关。
    如果不加这个中间件,如果接口是get请求而前端使用post请求,会返回 404 状态码,接口未定义。如果加了这个中间件,这种情况时,会返回405 Method Not Allowed提示 request method 不匹配,并在响应头返回接口支持的请求方法,更有利于调试

    例如: 我们定义一个 /list 接口,他需要使用post请求方法。这里我们先通过get方法来请求这个接口试试。

    const koa = require('koa');
    const Router = require('koa-router')
     
    const app = new koa()
    const router = new Router()
     
    router.post('/list', ctx => {
      ctx.body = ["111","222","333"]
    })
     
    app.use(router.routes()).use(router.allowedMethods())
     
    app.listen('3000', () => {
      console.log('server listen on 3000 port')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述
    我们通过network查看后该接口报了405 Method Not Allowed的错误,在告诉我们该方法不被允许,并且提示我们Allow:POST,允许post方法。这样的话可以很方便的帮助我们开发,寻找错误更加高效。


    请求方式

    Koa-router 请求方式: getputpostpatchdeletedel ,而使用方法就是 router.方式() ,比如 router.get() router.post() 。而 router.all() 会匹配所有的请求方法。

    const Koa = require("koa")
    const Router = require("koa-router")
    
    const app = new Koa()
    const router = new Router()
    
    router.get("/user",(ctx)=>{
        ctx.body=["aaa","bbb","ccc"]
    })
    router.put("/user/:id",(ctx)=>{
        ctx.body={ok:1,info:"put user success"}
    })
    router.post("/user",(ctx)=>{
        ctx.body={ok:1,info:"user post success"}
    })
    router.del("/user/:id",(ctx)=>{
        ctx.body={ok:1,info:"user del success"}
    })
    
    
    app.use(router.routes()).use(router.allowedMethods())
    app.listen(3000)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    我们在这里使用postman测试其中一个方式即可:
    在这里插入图片描述


    拆分路由

    如果我们书写了很多个路由接口,都写到一个js文件中,未免非常的不合理,Koa框架与express框架一样,可以进行路由拆分

    在这里我们通过一个demo展示:

    • demo结构
      在这里插入图片描述

    • user.js路由文件

      const Router= require('koa-router')
      const router = new Router()
      //路由中间件
      router.post('/',(ctx,next)=>{
          console.log(ctx.request.body);  //获取前端传来的参数
          ctx.body = {
              ok : 1,
              info : "add user success"
          }
      })
      //获取信息
      router.get('/',(ctx,next)=>{
          //获取前端传来的数据
          console.log(ctx.query,ctx.querystring);
          ctx.body = ['aaa','vvv','ccc']
      })
      
      router.put('/:id',(ctx,next)=>{
          console.log(ctx.params);  //获取动态路由id
          ctx.body = {
              ok : 1,
              info : "put user success"
          }
      })
      router.delete('/:id',(ctx,next)=>{
          ctx.body = {
              ok : 1,
              info : "delete user success"
          }
      })
      
      module.exports = router
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
    • home.js路由文件

      const Router= require('koa-router')
      const router = new Router()
      
      //获取信息
      router.get('/',(ctx,next)=>{
          ctx.body = `
          
              

      home页面

      `
      }) module.exports = router
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    • list.js路由文件

      const Router= require('koa-router')
      const router = new Router()
      
      //路由中间件
      router.post('/',(ctx,next)=>{
          ctx.body = {
              ok : 1,
              info : "add list success"
          }
      })
      //获取信息
      router.get('/',(ctx,next)=>{
          ctx.body = ['111','222','333']
      })
      
      router.put('/:id',(ctx,next)=>{
          console.log(ctx.params);  //获取动态路由id
          ctx.body = {
              ok : 1,
              info : "put list success"
          }
      })
      router.delete('/:id',(ctx,next)=>{
          ctx.body = {
              ok : 1,
              info : "delete list success"
          }
      })
      
      module.exports = router
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
    • 路由集合文件(index.js 注意: 这个文件是routes文件夹里的)

      const Router = require('koa-router')
      const userRouter = require('./user')
      const listRouter = require('./list')
      const homeRouter = require('./home.js')
      const router = new Router()
      
      router.use("/user",userRouter.routes(),userRouter.allowedMethods())
      router.use('/list',listRouter.routes(),listRouter.allowedMethods())
      router.use('/home',homeRouter.routes(),listRouter.allowedMethods())
      
      module.exports = router
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 项目入口文件(index.js)

      const Koa = require('koa')
      const app = new Koa(
      
      //先注册路由级组件
      const router = require('./routes')  //在这里会默认访问routes文件夹下的index.js文件
      //应用级组件
      
      //将router里所有的路由注册成应用级别的中间件
      app.use(router.routes()).use(router.allowedMethods())
      
      app.listen(3000)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    路由前缀

    const Router = require('koa-router')
    const userRouter = require('./user')
    const listRouter = require('./list')
    const homeRouter = require('./home.js')
    const router = new Router()
    
    //统一加前缀
    router.prefix("/api")
    
    router.use("/user",userRouter.routes(),userRouter.allowedMethods())
    router.use('/list',listRouter.routes(),listRouter.allowedMethods())
    router.use('/home',homeRouter.routes(),listRouter.allowedMethods())
    
    module.exports = router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    直接添加一个方法router.prefix()即可,这样的话就可以添加你的自定义前缀了。


    路由重定向

    const Router = require('koa-router')
    const userRouter = require('./user')
    const listRouter = require('./list')
    const homeRouter = require('./home.js')
    const router = new Router()
    
    router.use("/user",userRouter.routes(),userRouter.allowedMethods())
    router.use('/list',listRouter.routes(),listRouter.allowedMethods())
    router.use('/home',homeRouter.routes(),listRouter.allowedMethods())
    //重定向
    //写法1 
    router.redirect('/', '/home');
    //写法2
    router.get("/",(ctx)=>{
        ctx.redirect("/home")
    })
    
    module.exports = router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    使用方法router.redirect()即可,在这里我们访问http://localhost:3000/便会自动定位到http://localhost:3000/home页面中去。


    静态资源

    安装koa-static中间件:

    npm i koa-static
    
    • 1

    示例代码如下:

    const Koa = require('koa')
    const path = require('path')
    const static = require('koa-static')
    
    const app = new Koa()
    
    app.use(static(
      path.join( __dirname,  "public")
    ))
    
    
    app.use( async ( ctx ) => {
      ctx.body = 'hello world'
    })
    
    app.listen(3000, () => {
      console.log('[demo] static-use-middleware is starting at port 3000')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    获取请求参数

    get参数

    在koa中,获取GET请求数据源头是koa中request对象中的query方法或querystring方法,query返回的是格式化好的参数对象,querystring返回的是请求字符串,由于ctx对request的API有直接引用的方式,所以获取GET请求数据有两个途径。

    • 从上下文中直接获取 请求对象ctx.query,返回如 { a:1, b:2 }
      请求字符串 ctx.querystring,返回如 a=1&b=2
    • 从上下文的request对象中获取 请求对象ctx.request.query,返回如{ a:1, b:2 }
      请求字符串 ctx.request.querystring,返回如 a=1&b=2

    补充:
    获取动态路由的参数,执行请求对象: ctx.params即可!


    post参数

    对于POST请求的处理,koa-bodyparser中间件可以把koa2上下文的formData数据解析到ctx.request.body中。

    安装koa-bodyparser中间件:

    npm i koa-bodyparser
    
    • 1

    使用示例:

    const Koa = require('koa')
    const app = new Koa()
    const bodyParser = require('koa-bodyparser')
    //先注册路由级组件
    const router = require('./routes')
    //应用级组件
    //将router里所有的路由注册成应用级别的中间件
    app.use(bodyParser())  //获取前端传来的post参数
    app.use(router.routes()).use(router.allowedMethods())
    
    app.listen(3000)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    小结

    本篇文章讲解了koa框架中的路由、静态资源、获取请求参数,接下来的文章将对之前express框架中的知识进行“Koa化”,同时博主已经准备进行全栈项目的开发练手了,项目基于vue(2和3还没有想好) + Element ui + node.js + mysql开发,希望大家后期可以持续关注哦!

    在这里插入图片描述

  • 相关阅读:
    数据结构——单调栈
    Django 简单入门(一)
    【数理方程】分离变量法
    【重温基础算法】内部排序之归并排序法
    大模型在数据分析场景下的能力评测|进阶篇
    Spring入门
    springboot+篮球场馆预约系统 毕业设计-附源码211706
    虚拟货币(也称为加密货币或数字货币)的运作
    Go Through an ML project
    Java 调用Python+Opencv实现图片定位
  • 原文地址:https://blog.csdn.net/m0_52040370/article/details/127630295