摘要:框架中间件作为的老牌框架是现有框架中最全面的。然而在学习除了那些之外,对于框架最重要的就是中间件这个概念了。中间件功能可以执行以下任务执行任何代码对请求和响应对象进行更改。结束请求响应周期。调用堆栈中的下一个中间件。
express.js框架中间件(middleware)
_express.js_作为_Node.js_的老牌框架,是现有框架中最全面的。然而在学习express除了那些api之外,对于框架最重要的就是__中间件__这个概念了。如果理解了,就可以把这个框架玩活了,项目开发肯定会更加顺利,而且还可以开发很多额外的功能,甚至中间件扩展开发。
但是就这么一个东西,是很多学习node.js的小萌新们就算写出一个博客项目,都不知道它到底有啥作用。我当时在理解的时候也花了不少功夫,趁着没有啥工作,给各位学习express.js的一点点我的指导意见。当然,这里面可能也有koa2和egg的忠实粉丝,但其实所有node框架貌似都有这个概念,所以我用express举例子,希望各位将就一下哈,应该都是可以看得懂的。
首先我先来一波官方的解释:
好吧,被这些英语吓到了,来一波译文:
[中间件函数是可以访问请求对象(req)、响应对象(res)和应用程序请求响应周期中的下一个函数的函数。下一个函数是Express路由器中的一个函数,当调用该函数时,它执行当前中间件之后的中间件。
中间件功能可以执行以下任务:
执行任何代码
对请求和响应对象进行更改。
结束请求响应周期。
调用堆栈中的下一个中间件。
终于知道当初的我为毛刚开始理解的时候很困难了,说实在的看得我真的有懵的。幸好,我还是从这个坑爬出来了,我来拉你们一把了。首先我们不去深究概念,直接上一个代码块。
如果我们启动服务,访问"/"路由,会返回"这是一个根路由",访问router1路由就会得到这是一个"这是一个router1路由的"的信息。这看起来是一个很简单的路由查询,我们理一下过程,这个请求是如何访问到这个路由的呢。
一般来说,一个express框架的项目会写入很多路由,但各位要注意的是,这个请求并不是直接定位到这个路由的,而是一个从上至下匹配的一个过程。
有点乱?没关系我们看图
我们看到这幅图,有一个箭头,从上到下的。什么意思呢,如果用户发了一个这样的请求
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这个玩意有点启发了?
我是小龙,希望对大家有所帮助
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/103229.html
摘要:原文译者如果你曾经去过一个坐下来就餐的餐厅,那么你可以了解的基础知识。而且由于缺少路径,它将在每个请求上运行。这就是路由的来源。到目前为止,你已经雇佣了一位经理,在接受客户请求之前定义了要做的事情,并且确定如何处理特定的客户请求。 showImg(https://segmentfault.com/img/bVYnBo?w=4000&h=2666); 原文:Going out to e...
摘要:入口文件在文件夹下的,其向外界暴露了一些方法。方法也是从中继承的。入口文件很清晰,主要是完成方法的暴露以及的一些初始化操作。下一篇写写路由的实现。 还没用express写过server,先把部分源码撸了一遍,各位大神求轻拍。 express入口文件在lib文件夹下的express.js,其向外界暴露了一些方法。 最主要的(express.js 第36-47行): function cr...
摘要:在后续的总结中,我会继续分析,并准备将一些值得分析的逐一解读,也会涉及一些。从一个官方示例开始这是官方给出的一个简单程序,运行后访问显示。第一行载入了框架,我们来看源代码中的。代码的开始定义了一个函数,函数有形参,,为回调函数。 这两天仔细看了看express的源码,对其的整个实现有了较清晰的认识,所以想总结一下写出来,如果有什么不对的地方,望指出。 这是第一篇,首先介绍一个最简单的...
摘要:关于的实现源码解读,版本为。主要为路由部分。返回到的遍历是通过尾递归的方式实现的,注意到被传入的方法中,中处理事情最后向传入,从而是否继续遍历取决于的实现是否调用的方法。 关于express.js的实现源码解读,版本为 4.14。主要为路由部分。 一个Web框架最重要的模块是路由功能,该模块的目标是:能够根据method、path匹配需要执行的方法,并在定义的方法中提供有关请求和回应的...
摘要:框架核心特性路由定义了路由表用于执行不同的请求动作。中间件可以设置中间件来响应请求。注册一个请求路由结束响应开启监听端口执行上面代码是一种实用工具,将为您的源的任何变化并自动重启服务器监控。 Express 简介 Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。使用 Express 可以快...
阅读 1585·2021-11-02 14:48
阅读 3630·2019-08-30 15:56
阅读 2745·2019-08-30 15:53
阅读 3190·2019-08-30 14:09
阅读 3076·2019-08-30 12:59
阅读 2832·2019-08-29 18:38
阅读 2658·2019-08-26 11:41
阅读 2185·2019-08-23 16:45