Koa框架

一、认识Koa

前面我们已经学习了express,另外一个非常流行的Node Web服务器框架就是Koa。

Koa官方的介绍:

  • koa:next generation web framework for node.js;
  • koa:node.js的下一代web框架;

事实上,koa是express同一个团队开发的一个新的Web框架:

  • 目前团队的核心开发者TJ的主要精力也在维护Koa,express已经交给团队维护了;
  • Koa旨在为Web应用程序和API提供更小、更丰富和更强大的能力;
  • 相对于express具有更强的异步处理能力(后续我们再对比);
  • Koa的核心代码只有1600+行,是一个更加轻量级的框架,我们可以根据需要安装和使用中间件;

事实上学习了express之后,学习koa的过程是很简单的;

二、Koa初体验

我们来体验一下koa的Web服务器
koa注册的中间件提供了两个参数:

  1. ctx:上下文(Context)对象;
    koa并没有像express一样,将req和res分开,而是将它们作为ctx的属性;
    ctx代表依次请求的上下文对象;
    ctx.request:获取请求对象;
    ctx.response:获取响应对象;

  2. next:本质上是一个dispatch,类似于之前的next;
    后续我们学习Koa的源码,来看一下它是一个怎么样的函数;

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

三、Koa中间件

koa通过创建的app对象,注册中间件只能通过use方法:

  • Koa并没有提供methods的方式来注册中间件;
  • 也没有提供path中间件来匹配路径;
    在这里插入图片描述

但是真实开发中我们如何将路径和method分离呢?

  • 方式一:根据request自己来判断;
  • 方式二:使用第三方路由中间件;

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

四、路由的使用

koa官方并没有给我们提供路由的库,我们可以选择第三方库:koa-router
我们可以先封装一个 user.router.js 的文件:
在这里插入图片描述

在app中将router.routes()注册为中间件:
在这里插入图片描述
在这里插入图片描述

注意:allowedMethods用于判断某一个method是否支持:

  • 如果我们请求 get,那么是正常的请求,因为我们有实现get;
  • 如果我们请求 put、delete、patch,那么就自动报错:Method Not Allowed,状态码:405;
  • 如果我们请求 link、copy、lock,那么久自动报错:Not Implemented,状态码:501;

在这里插入图片描述

在这里插入图片描述

五、参数解析:params - query

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

六、参数解析:json && x-www-form-urlencoded

安装依赖: npm install koa-bodyparser;
使用 koa-bodyparser的中间件;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

七、参数解析:form-data

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

八、Multer上传文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

const path = require('path')
const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
const multer = require('koa-multer')
const app = new Koa()
const Router = require('koa-router')
const uploadRouter = new Router({prefix: '/upload'})
app.use(bodyParser())
const storage = multer.diskStorage({destination: (req, file, cb) => {cb(null, './uploads/')},filename: (req, file, cb) => {cb(null, Date.now() + path.extname(file.originalname))},
})
const upload = multer({storage
})
// app.use(upload.any())
uploadRouter.post('/avatar', upload.single('avatar'), (ctx, next) => {console.log(ctx)console.log(ctx.req.file)ctx.response.body = 'upload success~'
})
app.use(uploadRouter.routes())
// userRouter.post('/products', (ctx, next) => {
//     console.log(ctx.request.url)
//     console.log(ctx.request.body)
//
//     ctx.response.body = 'hello world~'
// })// app.use((ctx, next) => {
//     console.log(ctx.request.url)
//     console.log(ctx.request.query)
//     console.log(ctx.query)
//     ctx.response.body = 'hello world~'
// })
// app.use(userRouter.routes())
app.listen(8000, () => {console.log('koa服务器启动成功!')
})

九、数据的响应

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

请求状态:status
在这里插入图片描述
在这里插入图片描述

十、静态服务器

koa并没有内置部署相关的功能,所以我们需要使用第三方库:
npm install koa-static

部署的过程类似于express:
在这里插入图片描述
在这里插入图片描述

十一、错误处理

在这里插入图片描述
在这里插入图片描述

十二、koa和express对比

在学习了两个框架之后,我们应该已经可以发现koa和express的区别:

  1. 从架构设计上来说:
  • express是完整和强大的,其中帮助我们内置了非常多好用的功能;
  • koa是简洁和自由的,它只包含最核心的功能,并不会对我们使用其他中间件进行任何的限制。甚至是在app中连最基本的get、post都没有给我们提供;我们需要通过自己或者路由来判断请求方式或者其他功能;
  1. 因为express和koa框架他们的核心其实都是中间件:
    但是他们的中间件事实上,它们的中间件的执行机制是不同的,特别是针对某个中间件中包含异步操作时;

所以,接下来,我们再来研究一下express和koa中间件的执行顺序问题;

我通过一个需求来演示所有的过程:
假如有三个中间件会在一次请求中匹配到,并且按照顺序执行;
我希望最终实现的方案是:

  1. 在middleware1中,在req.message中添加一个字符串 aaa;
  2. 在middleware2中,在req.message中添加一个 字符串bbb;
  3. 在middleware3中,在req.message中添加一个 字符串ccc;
  4. 当所有内容添加结束后,在middleware1中,通过res返回最终的结果;

实现方案:
2. Express同步数据的实现;

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  1. Express异步数据的实现;
    在这里插入图片描述
const express = require('express')
const axios = require('axios')
const app = express()
const middleware1 = async (req, res, next) => {req.message = 'aaa'next()const message = await middleware3(req.message)console.log(message)res.end(message.toString())
}
const middlewar2 = async (req, res, next) => {req.message += 'bbb'
}
const middleware3 = async (msg) => {const result = await axios.get('http://123.207.32.32:9001/lyric?id=167876')msg += result.data.lrc.lyricconsole.log(msg)return msg
}
app.use(middleware1, middlewar2)
app.listen(8000, () =>{console.log('express服务器启动成功')
})
  1. Koa同步数据的实现;
    在这里插入图片描述

  2. Koa异步数据的实现;
    在这里插入图片描述
    注意:

在koa中,next()返回的是一个promise对象,所以可以通过await next()来实现需求。
在这里插入图片描述

但是在express中,next()只是一个普通的函数,所以使用await next()无效!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470338.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Node使用MySQL

一、认识mysql2 如何可以在Node的代码中执行SQL语句来,这里我们可以借助于两个库: mysql:最早的Node连接MySQL的数据库驱动;mysql2:在mysql的基础之上,进行了很多的优化、改进;目前相对来说&a…

java安装后在哪里打开_冷却塔声屏障安装后降噪效果不理想,原因出在哪里?...

现有冷却塔大部分产品都不能满足噪音环保标准,只有少数几种低吨位超低噪声型号的冷却塔可以满足少部分区域噪声标准要求。在一些商住混合区,冷却塔的出风口强烈的噪声和热气往往干扰附近居民不得安宁,所以冷却塔的噪声问题成为环境投诉的热点…

iOS10 权限崩溃问题

iOS10 权限崩溃问题 原文: http://blog.csdn.net/runleelrg/article/details/51673025 今天 手机升级了 iOS10 Beta,然后用正在开发的项目 装了个ipa包,发现点击有关 权限访问 直接Crash了,并在控制台输出了一些信息: This app h…

Koa框架——coderhub实战

https://github.com/zep03/koa-coderhub/commits/main 一、coderhub功能接口说明 Coderhub旨在创建一个程序员分享生活动态的平台。 完整的项目接口包括: 面向用户的业务接口;面向企业或者内部的后台管理接口; 完成的功能如下:…

python 协程_Python多任务协程

协程协程,又称微线程,纤程。英文名Coroutine。协程是python个中另外一种实现多任务的方式,只不过比线程更小占用更小执行单元(理解为需要的资源)。为啥说它是一个执行单元,因为它自带CPU上下文。这样只要在合适的时机,…

JavaScript高级之构造函数和原型

1.1 概述 在典型的 OOP 的语言中(如 Java),都存在类的概念,类就是对象的模板,对象就是类的实例,但在 ES6之前, JS 中并没用引入类的概念。 ES6, 全称 ECMAScript 6.0 ,2…

JavaScript高级之继承

ES6之前并没有给我们提供 extends 继承。我们可以通过构造函数原型对象模拟实现继承,被称为组合继承。 2.1 call() 调用这个函数, 并且修改函数运行时的 this 指向 fun.call(thisArg, arg1, arg2, …) thisArg :当前调用函数 this 的指向对象arg1&…

【代码笔记】iOS-UILable电子表显示

一&#xff0c;效果图。 二&#xff0c;代码。 RootViewController.h #import <UIKit/UIKit.h>interface RootViewController : UIViewController {UILabel *label;NSDateFormatter *dateFormatter ; } end RootViewController.m #import "RootViewController.h&qu…

JavaScript高级之ES5 中的新增方法

3.1 ES5 新增方法概述 ES5 中给我们新增了一些方法&#xff0c;可以很方便的操作数组或者字符串&#xff0c;这些方法主要包括&#xff1a; 数组方法字符串方法对象方法 3.2 数组方法 迭代(遍历)方法&#xff1a;forEach()、map()、filter()、some()、every()&#xff1b; …

JavaScript高级之函数进阶

1. 函数的定义和调用 1.1 函数的定义方式 函数声明方式 function 关键字 (命名函数)函数表达式 (匿名函数)new Function() Function 里面参数都必须是字符串格式第三种方式执行效率低&#xff0c;也不方便书写&#xff0c;因此较少使用所有函数都是 Function 的实例(对象)…

react 前端解析二进制流_一年半前端跳槽面试经验(头条、微信、shopee)

在2019年末的时候&#xff0c;突然想搞点大事&#xff0c;思来想去&#xff0c;感觉只有跳槽是最刺激的。由于我比较懒&#xff0c;不想换城市&#xff0c;所以这次只面试了头条、微信和 shopee。十分幸运&#xff0c;都拿到了 offer。接下来就简单的说下大家关心的面试题吧。问…

国内app快速生成平台对比

泰格老虎 2013-03-07 00:39:10 这是海恒CEO高鹏写的一篇国内app快速生成平台对比文章&#xff0c;介绍了国内快速生成APP的平台与自己平台的对比&#xff0c;很有参考价值。同类网站安米网 http://www.appbyme.org/追信 http://app.zhui.cn/简网app工厂 http://app.cutt.com/ap…

JavaScript高级之正则表达式

1. 正则表达式概述 1.1 什么是正则表达式 正则表达式&#xff08; Regular Expression &#xff09;是用于匹配字符串中字符组合的模式。在 JavaScript中&#xff0c;正则表达式也是对象。 正则表通常被用来检索、替换那些符合某个模式&#xff08;规则&#xff09;的文本&am…

pushpop指令的操作数必须是字操作数_PLC的指令,电气人必须了解的基础内容

指令语句表编程语言是所有PLC都具有的最基本的编程语言。而指令语句表程序是由一条一条的指令堆砌而成的。因此&#xff0c;我们有必要对指令进行进一步的说明和解读。1、指令格式PLC的指令语句表程序和微机汇编语言程序非常的相似&#xff0c;我们也是以汇编语言的指令和指令系…

JavaScript高级之ECMAScript 6 新特性

2.1. let关键字 let关键字用来声明变量&#xff0c;使用 let声明的变量有几个特点&#xff1a; 不允许重复声明 块儿级作用域 不存在变量提升 不影响作用域链 应用场景&#xff1a;以后声明变量使用let就对了 案例&#xff1a;点击切换颜色 <!DOCTYPE html&g…

sql 关联使用id还是code_R语言实例:用glue批量生成SQL语句

背景在数据开发中&#xff0c;有些情况下&#xff0c;需要手动生成批量SQL&#xff0c;只需改变某个参数&#xff0c;比如日期&#xff0c;从某天到某天。之前有一个实例&#xff0c;是用 stringr::str_replace_all() 去实现&#xff0c;这次就用 glue 来做示例&#xff0c;会更…

JavaScript高级之ECMASript 7、8 、9 、10 新特性

第3章 ECMASript 7 新特性 3.1. Array.prototype.includes Includes 方法用来检测数组中是否包含某个元素&#xff0c;返回布尔类型值 3.2. 指数操作符 在ES7中引入指数运算符「 **」&#xff0c;用来实现幂运算&#xff0c;功能与 Math.pow结果相同 第4章 ECMASript 8 新特…

swagger core 和 swagger ui 如何关联【窥探】

几个片段&#xff1a; package io.swagger.jaxrs.listing;import io.swagger.annotations.ApiOperation; import org.apache.commons.lang3.StringUtils;import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.ws.rs.GET; import javax.ws.r…

vb 根据pid获取句柄_C++中避免返回指向对象内部的句柄(handles)

点蓝色字关注“CurryCoder的程序人生”微信公众号&#xff1a;CurryCoder的程序人生欢迎关注我&#xff0c;一起学习&#xff0c;一起进步!1.问题的引入假如你正在给一个应用写一个矩形类&#xff0c;这个矩形由左上角和右下角的顶点坐标表示。为了表示这两个点&#xff0c;我们…

关于MapReduce中自定义Combine类(一)

MRJobConfigpublic static fina COMBINE_CLASS_ATTR属性COMBINE_CLASS_ATTR "mapreduce.job.combine.class"————子接口&#xff08;F4&#xff09; JobContent方法getCombinerClass————子实现类 JobContextImpl实现getCombinerClass方法&#xff1a;public C…