Egg是基于koa的,因此Egg的中间件和Koa的中间件是类似的。都是基于洋葱圈模型的。

在Egg中,比如我想禁用某些IP地址来访问我们的网页的时候,在egg.js中我们可以使用中间件来实现这个功能,中间件的作用无非就是说在Egg的外层在包一层来判断某些事情是否符合要求,也就是在洋葱圈模型外面再进行包一层。
在Egg入门二学习中(https://www.cnblogs.com/tugenhua0707/p/10226799.html), 我们最后的项目的目录结构如下:

egg-demo2
├── app
│ ├── controller
│ │ └── home.js
| | |-- index.js
│ └── router.js
│ ├──public
| | |---css
| | | |-- index.css
| | |---js
| | | |-- index.js
| |--- view
| | |-- index
| | | |-- list.tpl(模板文件list)
| |--- service
| | |--- index.js
├── config
│ └── config.default.js
└── package.json

在Egg中,中间件也有自己的配置和目录,因此在Egg中约定了中间件是放在 app/middleware 目录中的文件。该文件需要exports一个普通的function. 因此整个项目的目录变成如下这个样子:

egg-demo2
├── app
│ ├── controller # 用于解析用户的输入,处理后返回响应的结果
│ │ └── home.js
| | |-- index.js
│ └── router.js # 用于配置url路由的配置规则
│ ├──public # 资源文件目录
| | |---css
| | | |-- index.css
| | |---js
| | | |-- index.js
| |--- view # 存放模板文件的目录
| | |-- index
| | | |-- list.tpl(模板文件list)
| |--- service # 编写业务逻辑的目录
| | |--- index.js
| |--- middleware # 用于编写中间件的目录
| | |--- xxx.js
├── config # 相关的配置文件
│ └── config.default.js
└── package.json

编写中间件

我们在 app/middleware 目录中 新建一个 forbidIp.js 文件,该文件的作用是 禁用某些ip地址访问我们的网页。因此代码编写如下:

module.exports = (options, app) => {
return async function forbidIp(ctx, next) {
console.log(options);
console.log('---------');
console.log(app); // 需要被屏蔽的id
const ids = options.forbidips;
// 获取客户端的ip
const clientIp = ctx.request.ip; const isHasIp = ids.some(val => {
if (val === clientIp) {
return true;
}
return false;
});
if (isHasIp) {
ctx.status = 403;
ctx.body = '您的IP已经被屏蔽掉了';
} else {
await next();
}
}
}

使用中间件

如上中间件编写完成后,我们还需要手动挂载中间件。因此我们需要在 config/config.default.js 中加入下面的配置就可以完成了中间件的开启和配置:代码如下:

// 配置需要的中间件,数组的顺序即为中间件加载的顺序
exports.middleware = [
'forbidIp'
];
// 上面中间件的配置 ip
exports.forbidIp = {
forbidips: [
'192.168.1.12',
'127.0.0.1',
]
}

注意:如上 exports.middleware = ['forbidIp']; 该 forbidIp 指向与 app/middleware 中的 forbidIp.js, 因此需要注意大小写。也就是说是 forbidIp.js 中间件。然后下面的 exports.forbidIp = {}; forbidIp中间件的名字也需要一样的。exports.forbidIp 里面的对象就是中间件的ip配置了。

如上中间件代码,它接收两个参数:options 和 app;
options参数指的是 app.config[${middlewareName}]传进来。我们在 如上中间件代码中打印 options; console.log(options); 及 打印 console.log(app); 如下图所示:

可以看到 console.log(options); options参数的值就是 config配置项中的

{
forbidips: [
'192.168.1.12',
'127.0.0.1',
]
}

打印 config.log(app) 的值,如上图所示;它的含义是指 当前应用Application的实列。

因此我们继续访问 http://127.0.0.1:7001/ 后可以看到如下信息,页面被禁用了。如下图所示:

如果我们继续把 config/config.default.js 配置代码改成其他的ip地址,代码如下:

// 配置需要的中间件,数组的顺序即为中间件加载的顺序
exports.middleware = [
'forbidIp'
];
// 上面中间件的配置 ip
exports.forbidIp = {
forbidips: [
'192.168.1.12',
'127.0.0.12'
]
}

我们继续访问 http://127.0.0.1:7001/ 后,页面就正常了。如下所示:

二:在 router.js路由中使用中间件。

如上使用中间件都是全局的,每一次请求都会处理的,但是有时候我想针对单个路由生校的话,我们就不需要再 config中配置了。我们直接在路由中配置即可。

router.js在未使用中间件处理之前代码是如下:

module.exports = app => {
const { router, controller } = app;
router.get('/', controller.home.index);
router.get('/index', controller.index.list);
}

现在我们需要在 router.get('/'); 下使用禁用ip中间件,因此我们可以先注释掉 config中全局的中间件配置。我们可以直接在 router.js 下处理即可,如下代码所示:

首先:config/config.default.js 代码注释掉中间件:

/*
// 配置需要的中间件,数组的顺序即为中间件加载的顺序
exports.middleware = [
'forbidIp'
];
// 上面中间件的配置 ip
exports.forbidIp = {
forbidips: [
'192.168.1.12',
'127.0.0.12'
]
}
*/

然后在单个路由中使用中间件, router.js的代码如下:

module.exports = app => {
const { router, controller } = app; // 路由中使用中间件
const forbidIp = app.middleware.forbidIp({
forbidips: [
'127.0.0.1'
]
}); router.get('/', forbidIp, controller.home.index);
router.get('/index', controller.index.list);
}

然后我们继续访问 http://127.0.0.1:7001/ 后,页面也会提示该ip地址已经被屏蔽掉了。

更多的关于中间件配置介绍,请看官网中介绍的(https://eggjs.org/zh-cn/basics/middleware.html)

查看github源码中中间件代码

Egg入门学习(三)---理解中间件作用的更多相关文章

  1. Egg入门学习(二)---理解service作用

    在上一篇文章 Egg入门学习一 中,我们简单的了解了Egg是什么东西,且能做什么,这篇文章我们首先来看看官网对Egg的整个框架的约定如下,及约定对应的目录是做什么的,来有个简单的理解,注意:我也是按照 ...

  2. SCARA——OpenGL入门学习三

    OpenGL入门学习[三] 在第二课中,我们学习了如何绘制几何图形,但大家如果多写几个程序,就会发现其实还是有些郁闷之处.例如:点太小,难以看清楚:直线也太细,不舒服:或者想画虚线,但不知道方法只能用 ...

  3. SpringMVC入门学习三

    今天是Springmvc学习的第三天,今天我将主要介绍一下: 常用注解的使用 关于非post.get请求的处理 文件上传与下载 拦截器   常用注解的使用 老大在此 @Controller @Cont ...

  4. Egg入门学习(一)

    一:什么是Egg? 它能做什么?Egg.js是nodejs的一个框架,它是基于koa框架的基础之上的上层框架,它继承了koa的,它可以帮助开发人员提高开发效率和维护成本.Egg约定了一些规则,在开发中 ...

  5. iOS中 Swift初级入门学习(三)

    // // main.swift // LessonSwift-03 // // Copyright (c) 2015年 韩俊强. All rights reserved. // import Fou ...

  6. MongoDB入门学习(三):MongoDB的增删查改

            对于我们这样的菜鸟来说,最重要的不是数据库的管理,也不是数据库的性能,更不是数据库的扩展,而是怎么用好这款数据库,也就是一个数据库提供的最核心的功能,增删查改.         由于M ...

  7. 第15.21节 PyQt(Python+Qt)入门学习:QListView的作用及属性详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 QListView是从QAbstractItemView 派生的类,实现了QAbstrac ...

  8. dubbo入门学习 三 dubbo简介

    http://dubbo.apache.org/zh-cn/docs/user/references/protocol/dubbo.html Dubbo简介 1. Dubbo:一个分布式.高性能.透明 ...

  9. 【Go入门学习】理解区分数组和切片

    一.前言 学过 Go 的都知道在 Go 语言中有四种复合数据类型:数组.切片(Slice).哈希表(Map)和结构体(Struct),而很多 Go 初学者也很容易把数组和切片弄混淆,所以要怎么把这两个 ...

随机推荐

  1. jQuery 简单案例

    案例一:全选.反选.取消实例 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  2. 一次断电引发的svn数据库故障

    作者:朱金灿 来源:http://blog.csdn.net/clever101 昨天办公室停电了.然后今天更新svn数据库时出现一个不能读取文件:End of file found的错误,具体如下图 ...

  3. Python基于Python实现批量上传文件或目录到不同的Linux服务器

    基于Python实现批量上传文件或目录到不同的Linux服务器   by:授客 QQ:1033553122 实现功能 1 测试环境 1 使用方法 1 1. 编辑配置文件conf/rootpath_fo ...

  4. Python Python实现批量安装android apk包

    基于Python实现批量安装android apk包 by:授客 QQ:1033553122 1.相关软件包及文件下载 下载地址:adb软件包及批量安装apk包的py文件.zip 2.测试环境 Win ...

  5. Jmeter接口测试问题及解决方法积累

    一.各个类型参数的位置 plain body query parameter URI 路径上 二.特殊字符处理 \"作为参数输入到接口,会出现错误 响应断言中如果有用到正则表达式,不能包含正 ...

  6. 【Spring源码解读】bean标签中的属性

    说明 今天在阅读Spring源码的时候,发现在加载xml中的bean时,解析了很多标签,其中有常用的如:scope.autowire.lazy-init.init-method.destroy-met ...

  7. mongodb安装失败与解决方法(附安装教程)

    安装mongodb遇到的一些坑 浪费了大量的时间 在此记录一下   主要是电脑系统win10企业版自带的防火墙  当然还有其他的一些坑 一般的问题在第6步骤都可以解决,本教程的安装步骤不够详细的话  ...

  8. 转:RowVersion 用法

    在数据表更新时,如何表征每个数据行更新时间的先后顺序?最简单的做法是使用RowVersion(行版本)字段,它和时间戳(TimeStamp)类型的功能相似,只不过TimeStamp 已过时,应避免用于 ...

  9. python简单的监控脚本-利用socket、psutil阻止远程主机运行特定程序

    python简单的监控脚本-利用socket.psutil阻止远程主机运行特定程序 psutil是一个跨平台的库(http://code.google.com/p/psutil/),能够轻松的实现获取 ...

  10. reportComplaints.js: Uncaught TypeError: Cannot read property 'message' of undefined

    vonic 中遇到这么个问题, 一直提示我未定义, 可是明明有定义 var tab={ message:{ number:'', title:'' } } var id= { template: '# ...