express.js框架中间件(middleware)_express.js_作为_Node.js_的老牌框架,是现有框架中最全面的。不过学习express除了那些API之外,框架最重要的还是__middleware__这个概念。懂了就可以用这个框架来玩,项目开发肯定会更顺利,还可以开发很多附加功能,甚至是中间件扩展开发。但是就是这么一个东西,很多学习node.js的新手即使写了一个博客项目,也不知道它是干什么的。我也是费了很大力气去理解的。趁着工作上的空虚,给大家一点点学习express.js的指导。当然也可能有koa2和egg的忠实粉丝,但其实所有的node框架好像都有这个概念,所以我以express为例,希望大家看看,应该可以理解。首先来一波官方解释:嗯,被这些英文吓到,这里来一波翻译:【中间件函数可以访问请求对象(req),响应对象(res)和应用程序请求响应循环A功能为下一个功能。next函数是Express路由器中的一个函数,调用时会执行当前中间件之后的中间件。中间件功能可以执行以下任务:执行任何代码以更改请求和响应对象。结束请求响应周期。调用堆栈中的下一个中间件。我终于明白,刚开始了解微猫的时候,是非常困难的。老实说,我真的很困惑。幸运的是,我还是从这个坑里爬了出来,我是来助你一臂之力的。首先我们先不深究概念,直接上一个代码块。如果我们启动服务并访问'/'路由,它会返回“这是一个根路由”,如果我们访问router1路由,我们会得到消息“这是一个router1路由”。这似乎是一个非常简单的路由查询。我们来看看这个过程,这个请求是如何访问这个路由的。一般来说,express框架的一个项目会写很多路由,但是大家要注意,这个请求并不是直接定位到这个路由,而是一个从上到下匹配的过程。有点乱?没关系,我们看图,我们看这张图,有一个箭头,从上到下。这是什么意思?如果用户发出GET'/router7'这样的请求,他就会从第一个开始一个一个开始匹配。当他发现路由名称和请求方法相同的路由时,他会立即执行里面的代码。并返回一段文字“Thisisarouter7route”。这个好理解,所以现在我有一个需求,就是无论访问哪条路由,都需要知道访问者的ip地址和访问的目标路由,打印出来,产生访问日志。那么该怎么办。下面分析一波。该程序由所有请求执行。按照执行顺序,这个程序应该放在所有路由的最前面。也就是说,这个程序是所有路由都要经过的。一个程序,也就是我们所说的中间件。好了,废话不多说了,上面的代码constfs=require('fs')constlog=(req,res)=>{constip=req.ip,route=req.route.pathconstlog=`ip:${ip}path:${route}`fs.writeFileSync(__dirname+'/log',log)}比如我现在有一个日志功能,专门用来记录访问日志。如何全部一起执行呢,我们在所有代码的最前面加了一段代码app.use(log),但是加了之后还不行,必须在log中加一段代码函数,不然当里面的程序执行完后,就出不来了,什么代码。我们重写日志函数constlog=(req,res,next)=>{constip=req.ip,route=req.route.pathconstlog=`ip:${ip}path:${route}`fs.writeFileSync(__dirname+'/log',log)next()}接下来你看到了吗,它是做什么的?前面我们说了,它其实就是一个transition,它的主要作用是通过之后继续执行,或者终止并返回结果。简单的说,就是一个http请求到达我们的节点服务器之后,要经过的过程。每经过一个程序块,就是一个中间件。只要每个中间件有next,就会传递给下一个中间件。里面,直到serverres响应结果,整个路由到此结束。让我们把代码放在一起。为了简化它,运行程序constexpress=require('express')constapp=express()constlog=(req,res,next)=>{constip=req.ip,route=req.route.pathconstlog=`ip:${ip}path:${route}`fs.writeFileSync(__dirname+'/log',log)next()}app.use(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('applisteningonport3000!')})GET'/router2'//打印日志并返回结果这是一个简单的中间文档解释。你也可以回头看看你之前写的代码。对之前的使用有什么启发吗?我是小龙,希望对大家有所帮助
