koa2 从入门到进阶之路 (三)
之前的文章我们介绍了一下 koa 路由,get 传值,动态路由,本节我们看一下 koa 中间件 以及 koa 中间件的洋葱图执行流程。
一、什么是 Koa 的中间件
通俗的讲:中间件就是匹配路由之前或者匹配路由完成做的一系列的操作,我们就可以把它叫做中间件。
在express中间件(Middleware)是一个函数,它可以访问请求对象(request object (req)), 响应对象(response object (res)), 和 web 应用中处理请求-响应循环流程中的中间件,一般被命名为 next 的变量。在 Koa 中中间件和 express 有点类似。
中间件的功能包括:
执行任何代码。
修改请求和响应对象。
终结请求-响应循环。
调用堆栈中的下一个中间件。
如果我的 get、post 回调函数中,没有 next 参数,那么就匹配上第一个路由,就不会往下匹 配了。如果想往下匹配的话,那么需要写 next()
二、Koa 应用可使用如下几种中间件:
应用级中间件
路由级中间件
错误处理中间件
第三方中间件
我们先来看一下应用级中间件,我们还是按照之前的项目将 app.js 改为如下:
//引入 koa模块
var Koa = require('koa');
var Router = require('koa-router'); //实例化
var app = new Koa();
var router = new Router(); //匹配任何路由,如果不写next,这个路由被匹配到了就不会继续向下匹配
app.use(async (ctx, next) => {
console.log("我是一个中间件");
// 当前路由匹配完成以后继续向下匹配
await next();
}); //配置路由
router.get('/', async (ctx) => {
ctx.body = "首页";
});
router.get('/news', async (ctx) => {
ctx.body = "新闻列页面";
}); //启动路由
app.use(router.routes());
app.use(router.allowedMethods()); app.listen(3000);
我们在匹配路由之前写了一个 app.use(async ()=>{}) 的中间件,该中间件如果不像 router.get 那样写一个参数 "/" 或 "/news",那么它将匹配任何一个路由,且最先匹配,如果我们在其中写 next() 的话,则会终止在此,不再向下陪陪路由,运行结果如下:

我们在编辑器的控制台看一下输出日志:

接下来我们看一下路由中间件:
//引入 koa模块
var Koa = require('koa');
var Router = require('koa-router'); //实例化
var app = new Koa();
var router = new Router(); //配置路由
router.get('/', async (ctx, next) => {
console.log("控制台打印");
// 当前路由匹配完成以后继续向下匹配
await next();
});
router.get('/', async (ctx) => {
ctx.body = "首页";
});
router.get('/news', async (ctx) => {
ctx.body = "新闻列页面";
}); //启动路由
app.use(router.routes());
app.use(router.allowedMethods()); app.listen(3000);
在上面的代码中我们定义了两个 router.get('/', ) 的路由,第一个我们在控制台输出一句话,第二个我们想页面输出内容。如果在第一个里面我们不写 next() 方法的话,则不会进入第二个里面,结果如下:

控制台打印结果

接下来我们看一下错误处理中间件:
//引入 koa模块
var Koa = require('koa');
var Router = require('koa-router'); //实例化
var app = new Koa();
var router = new Router(); //匹配任何路由,如果不写next,这个路由被匹配到了就不会继续向下匹配
app.use(async (ctx,next)=>{
await next();
//如果页面找不到
if(ctx.status==404){
ctx.status = 404;
ctx.body="404 页面"
}
}); //配置路由
router.get('/', async (ctx) => {
ctx.body = "首页";
});
router.get('/news', async (ctx) => {
ctx.body = "新闻列页面";
}); //启动路由
app.use(router.routes());
app.use(router.allowedMethods()); app.listen(3000);
我们还按之前的应用中间件那样写,然后在里面做了一个 if 语句判断,当页面响应时,会给后端返回一个 status 码,这个就不在单独说了,如果这个 status 报 404,我们知道表示该页面不存在,那么我们就可以拦截 next() 方法,输出给前端一个 404 页面,结果如下:

我们匹配了一个 "/news" 路由,可以正常显示内容,如果我们不小心少写一个 "s",写成了 "new",结果如下:

在上面的代码中我们是将 if 判断语句放在了 next() 方法之后,那能不能放在 next() 之前呢?这个问题我们在下面的 koa 中间件流程控制中再详细说明。
第三方中间件在之后的文章中我们用到了第三方模块时再说。
接下来我么看一下 koa 中的中间件流程控制。
koa被认为是第二代node web framework,它最大的特点就是独特的中间件流程控制,是一个典型的洋葱模型。


上面的两张图可以很直观的说明 koa 中的中间件流程控制。我们接下来用代码演示一下:
//引入 koa模块
var Koa = require('koa');
var Router = require('koa-router'); //实例化
var app = new Koa();
var router = new Router(); app.use(async (ctx, next) => {
console.log('1、这是第一个中间件01');
await next();
console.log('5、匹配路由完成以后又会返回来执行中间件');
}); app.use(async (ctx, next) => {
console.log('2、这是第二个中间件02');
await next();
console.log('4、匹配路由完成以后又会返回来执行中间件');
}); router.get('/', async (ctx) => {
console.log('3、匹配到了news这个路由');
ctx.body = "首页";
}); //启动路由
app.use(router.routes());
app.use(router.allowedMethods()); app.listen(3000);
我们在上面的代码引用了两个应用级的中间件,分别在 next() 前后输出日志,当我们访问 localhost:3000/ 时,我们看一下控制台的输出结果:

从输出打印结果顺序我们可以看出中间件会先逐级处理 request 请求,然后再返回来逐级处理 response 请求,这就是我们为什么要将 错误处理中间件 中的 if 判断语句放在 next() 方法之后,这样就是在路由进入 "/news" 后返回 status = 404 的结果后再进行处理,如果放在了 next() 方法之前,则会直接判断 if 语句,不会再向下匹配 "/news" 路由了。比如我们的用户登录系统就可以这么用,当用户输入账号密码后出入后台,后台在数据库匹配之后再进行处理,处理之后返回给前端,就是这么玩的。
koa2 从入门到进阶之路 (三)的更多相关文章
- koa2 从入门到进阶之路 (二)
之前的文章我们已经能够在本地启动一个简单的项目,本章我们来看一下 koa 路由,get 传值,动态路由. 一.Koa 路由 路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP ...
- koa2 从入门到进阶之路 (一)
首先我们先来了解一下 Koa 是什么,https://koa.bootcss.com/,这是 Koa 的官方网站,映入眼帘的第一句就是 Koa -- 基于 Node.js 平台的下一代 web 开发框 ...
- koa2 从入门到进阶之路 (七)
之前的文章我们介绍了一下 koa koa-static静态资源中间件,本篇文章我们来看一下 koa 中 cookie 和 session 的使用. cookie 是存储于访问者的计算机中的变量.可以让 ...
- koa2 从入门到进阶之路 (五)
之前的文章我们介绍了一下 koa 中使用 ejs 模板及页面渲染,本篇文章我们来看一下 koa post提交数据及 koa-bodyparser中间件. 在前端页面中,不免会用到 form 表单和 p ...
- koa2 从入门到进阶之路 (四)
之前的文章我们介绍了一下 koa 中间件 以及 koa 中间件的洋葱图执行流程,本篇文章我们来看一下 koa 中使用 ejs 模板及页面渲染. 在 Express 中,我们经常会用 ejs 模板来渲染 ...
- koa2 从入门到进阶之路 (六)
之前的文章我们介绍了一下 koa post提交数据及 koa-bodyparser中间件,本篇文章我们来看一下 koa-static静态资源中间件. 我们在之前的目录想引入外部的 js,css,img ...
- Python 爬虫从入门到进阶之路(三)
之前的文章我们做了一个简单的例子爬取了百度首页的 html,本篇文章我们再来看一下 Get 和 Post 请求. 在说 Get 和 Post 请求之前,我们先来看一下 url 的编码和解码,我们在浏览 ...
- Python 从入门到进阶之路(三)
在之前的文章我们介绍了一下 Python 中 if while for 的使用,本章我们来看一下 Python 中的变量类型. 在 Python 定义变量时的规则是 变量名 = 变量 ,Python ...
- React 从入门到进阶之路(三)
之前的文章我们介绍了 React 创建组件.JSX 语法.绑定数据和绑定对象.接下来我们将介绍 React 绑定属性( 绑定class 绑定style).引入图片 循环数组渲染数据. 上一篇中我们 ...
随机推荐
- java模式及其应用场景
最经典的java 23种设计模式及具体例子(转发) 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容 ...
- Diycode开源项目 TopicContentActivity分析
1.效果预览以及布局分析 1.1.实际效果预览 左侧话题列表的布局是通过TopicProvider来实现的,所以当初分析话题列表就没有看到布局. 这里的话题内容不是一个ListView,故要自己布局. ...
- 第一次接触php
一.什么是PHP PHP的中文意思:超文本预处理器,英文名字: HyperText Preprocessor. PHP通常有两层含义: (1)PHP是一个编程语言. (2)PHP是处理PHP编程语言的 ...
- leetcode 【 Maximum Subarray 】python 实现
题目: Find the contiguous subarray within an array (containing at least one number) which has the larg ...
- 引用其他头文件时出现这种错误,莫名其妙,error C2065: “ColorMatrix”: 未声明的标识符
今天做项目时,直接拷贝了另一个工程里的头文件和源文件,然后运行时就出现这种问题,莫名其妙,在原程序里运行一点问题就没有,但是在新工程里就是error. >e:\c++\button_fly2\b ...
- Eclipse启动错误:A Java Runtime Environment(JRE) or Java Development Kit(JDK) must be available……
确保Jdk,Jre都安装完成并且环境变量配置无误的情况下,自动Ecplise报错如下: A Java Runtime Environment (JRE) or Java Development Kit ...
- Leetcode 654.最大二叉树
最大二叉树 给定一个不含重复元素的整数数组.一个以此数组构建的最大二叉树定义如下: 二叉树的根是数组中的最大元素. 左子树是通过数组中最大值左边部分构造出的最大二叉树. 右子树是通过数组中最大值右边部 ...
- Leetcode 600.不包含连续1的非负整数
不包含连续1的非负整数 给定一个正整数 n,找出小于或等于 n 的非负整数中,其二进制表示不包含 连续的1 的个数. 示例 1: 输入: 5 输出: 5 解释: 下面是带有相应二进制表示的非负整数&l ...
- 一个iOS程序员眼中的跨域问题
摘要: 跨域问题是web开发领域一个常见的问题,相信每个web开发者都遇到"跨域"的问题 最近公司的iOS开发任务比较少,所以自己最近开始了Web开发的任务,在用H5做了很多页面, ...
- 微信Oauth2.0网页开放授权
网页授权获取用户基本信息 如果用户在微信中(Web微信除外)访问公众号的第三方网页,公众号开发者可以通过此接口获取当前用户基本信息(包括昵称.性别.城市.国家).利用用户信息,可以实现体验优化.用户来 ...