关于express中间件的简要解析之应用级、路由级中间件(一)

      Express 是一个自身功能极简,完全是由路由和中间件构成一个的 web 开发框架:从本质上来说,一个 Express 应用就是在调用各种中间件。中间件(Middleware) 是一个函数,它可以访问请求对象(request object (req)),响应对象(response object (res)), 和 web 应用中处于请求-响应循环流程中的中间件,一般被命名为 next 的变量。

中间件可以分为以下五种:

  1. 应用级中间件
  2. 路由级中间件
  3. 错误处理中间件
  4. 内置中间件
  5. 第三方中间件

        为加深理解需要做一些实例,首先要建立nodejs express 工程,在工程下随意创建一个目录,在该目录下建立三个文件 server.js、app.js和router.js。

server.js代码如下:

var http=require('http');

var app=require('./app');

var server=http.createServer(app);

server.listen(3000,function(){

console.log('server Listening on port 3000');

});

app.js 代码如下:

var express=require('express');

var app=express();

app.use(function(req,res){

     console.log('firstMiddleware')

});

module.exports=app;

router.js代码如下:

var express=require('express');

var router=express.Router();

router.use(function(req,res,next){

     console.log('firstMiddleware')

});

module.exports=router;

1、下面先对单个中间件进行详解:

        应用级中间件和路由级中间件用法相同(执行函数都是自己编写),应用级中间件使用方式为app.use([path,] function [, function...]) 和 app.METHOD([path,] function [, function...]);路由级中间件的使用方式为router.use([path,] function [, function...]) 和 router.METHOD([path,] function [, function...]) 其中,METHOD 是需要处理的 HTTP 请求的方法,例如 GET, PUT, POST 等等,所有请求方法都要小写,.use和.METHOD的两种用法也是相同的,下面以app.use()为例进行解析。

参数说明:

       path :为访问路径格式为 '/../..',可以省略,省略则所有请求都执行该中间件;

       function:为执行函数,每个中间件的执行函数可以为单个、多个、执行函数的数组,也可以是他们的组合,但至少得有一个执行函数;下面对他们分别介绍。

      ①单个执行函数:

         当前的app.js文件中的中间件即为典型的单个执行函数;

      ②多个执行函数:

         现把app.js文件修改为:

var express=require('express');

var app=express();

var f1=function(req,res,next){

console.log('firstMiddleware  f1')

     next();

};

varf2=function(req,res,next){

     console.log('firstMiddleware  f2')

    next();

};

var f3=function(req,res,next){

     console.log('firstMiddleware  f3')

};

app.use(f1,f2,f3);

module.exports=app;

执行结果为:

firstMiddleware  f1

firstMiddleware  f2

firstMiddleware  f3

        此即为典型的多个执行函数。

        其中app.use(f1,f2,f3)可以修改为app.use(f1,[f2,f3])为函数与函数数组的结合,修改为app.use([f1,f2,f3])即为函数数组的方式;

       当一个中间件有多个执行函数时,前面的执行函数要调用next函数,不调用next函数,后面的函数将无法执行若该执行函数之前还未把res发出则会出现请求挂起,如:把f2 的 next()删除,再运行发出请求后请求将挂起,若把f2的next()删除后加上res.send('respose has sended!'); 则请求不再挂起但f3不会执行。由于路由中间件用法相同就不再详解。

 

2、下面对多个中间件之间的组合进行详解:

       当有多个中间件时,各个中间件以此与请求路径进行匹配,匹配成功则运行,不成功跳过,所有一般按匹配范围排列中间件,把匹配范围大的中间件放到前面(所有请求都执行的中间件匹配范围最大,所有一般都放到最前面)依次排列。

      现对app.js修改如下:

var express=require('express');

var app=express();

var f1=function(req,res,next){

console.log('firstMiddleware  f1');

next();

};

var f2=function(req,res,next){

     console.log('firstMiddleware  f2');

     next();

};

 

app.use(f1,f2);

app.use(function(req,res,next){

     console.log('secondMiddleware');

res.set({

     'Content-Type':'text/plain',

     'Content-Length':'123',

     'ETag':'12345'

     })

     next();

})

app.use('/hello',function(req,res,next){

     console.log('hello middleware');

     res.send('response has sended!');

});

module.exports=app;

 

       一般一个请求所匹配的所有中间件的执行函数除最后一个执行函数外都要调用next,否则后面的执行函数或中间件将无法执行,若res还未发出请求将会挂起,(其后的中间件也无法执行,即前面中间件的每个执行函数都有调用next,否则将不会再往后执行),若当前函数没有处理res 则会出现请求挂起,如把第二个中间件的next()删除后运行。若前面的函数或中间件已经将res发出,则后面的函数或中间件将不能在对res的header进行设置,否则会报错,如把app.js改为:

var express=require('express');

var app=express();

var f1=function(req,res,next){

console.log('firstMiddleware  f1');

next();

};

var f2=function(req,res,next){

     console.log('firstMiddleware  f2');

     next();

};

 

app.use(f1,f2);

app.use('/hello',function(req,res,next){

     console.log('hello middleware');

     res.send('response has sended!');

     next();

});

app.use(function(req,res,next){

     console.log('secondMiddleware');

res.set({

     'Content-Type':'text/plain',

     'Content-Length':'123',

     'ETag':'12345'

     })

})

module.exports=app;

当以上的代码执行时,发送请求会出现res已经发送不能对res的header进行设置的错误。

---------------------------------------------------------------------------------------------------------------------

未完待续!

关于express中间件的详细介绍请到:express中间件使用

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章