浅谈express.js框架中间件(middleware)


Posted in Javascript onApril 07, 2019

_express.js_作为_Node.js_的老牌框架,是现有框架中最全面的。然而在学习express除了那些api之外,对于框架最重要的就是__中间件__这个概念了。如果理解了,就可以把这个框架玩活了,项目开发肯定会更加顺利,而且还可以开发很多额外的功能,甚至中间件扩展开发。

但是就这么一个东西,是很多学习node.js的小萌新们就算写出一个博客项目,都不知道它到底有啥作用。我当时在理解的时候也花了不少功夫,趁着没有啥工作,给各位学习express.js的一点点我的指导意见。当然,这里面可能也有koa2和egg的忠实粉丝,但其实所有node框架貌似都有这个概念,所以我用express举例子,希望各位将就一下哈,应该都是可以看得懂的。

首先我先来一波官方的解释:

浅谈express.js框架中间件(middleware)

好吧,被这些英语吓到了,来一波译文:

[中间件函数是可以访问请求对象(req)、响应对象(res)和应用程序请求响应周期中的下一个函数的函数。下一个函数是Express路由器中的一个函数,当调用该函数时,它执行当前中间件之后的中间件。

中间件功能可以执行以下任务:

  • 执行任何代码
  • 对请求和响应对象进行更改。
  • 结束请求响应周期。
  • 调用堆栈中的下一个中间件。

终于知道当初的我为毛刚开始理解的时候很困难了,说实在的看得我真的有懵的。幸好,我还是从这个坑爬出来了,我来拉你们一把了。首先我们不去深究概念,直接上一个代码块。

浅谈express.js框架中间件(middleware)

如果我们启动服务,访问'/'路由,会返回"这是一个根路由",访问router1路由就会得到这是一个"这是一个router1路由的"的信息。这看起来是一个很简单的路由查询,我们理一下过程,这个请求是如何访问到这个路由的呢。

一般来说,一个express框架的项目会写入很多路由,但各位要注意的是,这个请求并不是直接定位到这个路由的,而是一个从上至下匹配的一个过程。

有点乱?没关系我们看图

浅谈express.js框架中间件(middleware)

我们看到这幅图,有一个箭头,从上到下的。什么意思呢,如果用户发了一个这样的请求

GET '/router7'

那么他会从第一个开始一个一个去匹配,知道发现有一个路由名和请求方法都一致的路由,就立马执行里面的代码,并且返回一段文字"这是一个router7路由"。这都很好理解,那么现在我有一个需求,就是不管访问任何一个路由,我都要知道这个访问者的ip地址和访问的目标路由打印出来,生产访问日志。那么怎么做了。

我们分析一波,这段程序是所有的请求都要执行的,如果按照执行顺序的说法,那么这段程序是应该放到所有路由的最前面的,也就是说这段程序是所有路由要经过的一段程序,也就是我们所说的中间件。好的,废话不多说,上代码

const fs = require('fs')
const log = (req,res) => {
  const ip = req.ip,
     route = req.route.path
  const log = `ip:${ip} path:${route}`
   fs.writeFileSync(__dirname + '/log',log)
}

比如现在我有一个log函数,它专门用来记录访问日志的。如何所有的都一起执行了,我们加一段这样的代码

app.use(log)

它加在所有代码的最上面,但是不是加上就完事了,还必须在log函数里面再加一段代码,不然当程序执行到里面之后就出不去了,什么代码了。我们重写log函数

const log = (req,res,next) => {
  const ip = req.ip,
     route = req.route.path
  const log = `ip:${ip} path:${route}`
   fs.writeFileSync(__dirname + '/log',log)
   next()
}

大家有没有看见那个next,它有什么作用了。前面我们提到,它其实就是一个过渡者,主要的作用其实就是经过之后,要继续往下面执行,还是就此终止返回结果。

说的简单一点,就是我们一个http请求,到达我们的node服务器之后,要经历的过程,而每经过一个程序块,就是个中间件,每一个中间件只要有next就会传递到下一个中间件里面,直到服务器res响应结果,整个路由就此结束。

我们整合一下代码。并且精简一下,也跑一遍程序

const express = require('express')
const app = express()

const log = (req,res,next) => {
  const ip = req.ip,
     route = req.route.path
  const log = `ip:${ip} path:${route}`
   fs.writeFileSync(__dirname + '/log',log)
   next()
}

app.use(log)//任何请求都会经过这个log中间件 

app.get('/', (req, res) => {
  console.log(req.route.stack)
  res.send('这是一个根路由!')
})

app.get('/router1', (req, res) => {
  res.send('这是一个router1路由!')
})
app.get('/router2', (req, res) => {
  res.send('这是一个router2路由!')
})


app.listen(3000, () => {
  console.log('app listening on port 3000!')
})
GET '/router2' //打印日志,并且返回结果

这就是一个简单的中间件解释了。大家也可以回去看看你原来写过的代码,是否对之前的use这个玩意有点启发了?

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
分享一个自己写的table表格排序js插件(高效简洁)
Oct 29 Javascript
浅析LigerUi开发中谨慎载入common.css文件
Jul 09 Javascript
js检测输入内容全为空格的方法
May 03 Javascript
js限制文本框只能输入整数或者带小数点的数字
Apr 27 Javascript
jQuery实现的简单提示信息插件
Dec 08 Javascript
给easyui的datebox控件添加清空按钮的实现方法
Nov 09 Javascript
基于JavaScript实现滑动门效果
Mar 16 Javascript
vue 和vue-touch 实现移动端左右导航效果(仿京东移动站导航)
Apr 22 Javascript
mpvue中使用flyjs全局拦截的实现代码
Sep 13 Javascript
JavaScript中十种一步拷贝数组的方法实例详解
Apr 22 Javascript
vue商城中商品“筛选器”功能的实现代码
Jul 01 Javascript
JavaScript中Object、map、weakmap的区别分析
Dec 15 Javascript
详解vue中this.$emit()的返回值是什么
Apr 07 #Javascript
浅谈javascript中的prototype和__proto__的理解
Apr 07 #Javascript
javascrit中undefined和null的区别详解
Apr 07 #Javascript
详解服务端预渲染之Nuxt(介绍篇)
Apr 07 #Javascript
vue设计一个倒计时秒杀的组件详解
Apr 06 #Javascript
js字符串处理之绝妙的代码
Apr 05 #Javascript
微信小程序自定义导航栏实例代码
Apr 05 #Javascript
You might like
php根据分类合并数组的方法实例详解
2013/11/06 PHP
thinkphp3查询mssql数据库乱码解决方法分享
2014/02/11 PHP
详解PHP导入导出CSV文件
2014/11/03 PHP
Yii2 RESTful中api的使用及开发实例详解
2016/07/06 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
2017/11/16 PHP
Apache+PHP+MySQL搭建PHP开发环境图文教程
2020/08/06 PHP
JavaScript中使用构造器创建对象无需new的情况说明
2012/03/01 Javascript
开发 Internet Explorer 右键功能表(ContextMenu)
2013/07/03 Javascript
JS方法调用括号的问题探讨
2014/01/24 Javascript
js获取页面传来参数的方法
2014/09/06 Javascript
javascript格式化json显示实例分析
2015/04/21 Javascript
三分钟带你玩转jQuery.noConflict()
2016/02/15 Javascript
jquery中用jsonp实现搜索框功能
2016/10/18 Javascript
微信小程序 Windows2008 R2服务器配置TLS1.2方法
2016/12/05 Javascript
canvas实现绘制吃豆鱼效果
2017/01/12 Javascript
基于vue的短信验证码倒计时demo
2017/09/13 Javascript
JS使用正则表达式找出最长连续子串长度
2017/10/26 Javascript
js jquery 获取某一元素到浏览器顶端的距离实现方法
2018/09/05 jQuery
微信小程序中转义字符的处理方法
2019/03/28 Javascript
使用layui的router来进行传参的实现方法
2019/09/06 Javascript
浅谈JSON5解决了JSON的两大痛点
2020/12/14 Javascript
如何在 Vue 表单中处理图片
2021/01/26 Vue.js
[02:36]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma 选手采访
2021/03/11 DOTA
Python群发邮件实例代码
2014/01/03 Python
python设置检查点简单实现代码
2014/07/01 Python
Python实现的生成自我描述脚本分享(很有意思的程序)
2014/07/18 Python
在python中bool函数的取值方法
2018/11/01 Python
微信小程序python用户认证的实现
2019/07/29 Python
银行竞聘演讲稿
2014/05/16 职场文书
应届毕业生自荐书
2014/06/18 职场文书
汇报材料怎么写
2014/12/30 职场文书
环保守法证明
2015/06/24 职场文书
通知怎么写?
2019/04/17 职场文书
7个你应该知道的JS原生错误类型
2021/04/29 Javascript
详细聊聊vue中组件的props属性
2021/11/02 Vue.js
iSCSI服务器CHAP双向认证配置
2022/04/01 Servers