Middleware(中间件)是Express中一个很是核心的概念。理解其工做原理对于编写能够维护网站、减小代码量具备很是重要的做用。css
从实现上看,Middleware和Route Handler同样,本质上都是函数。Middleware这个函数接受express传入3个参数:req,res和next。调用的方法就是app.use(function(req,res,next){....});
从处理过程上来看,middleware是处在请求Request和最终处理请求的Route Handler之间的一系列函数,它对于请求的内容在交由Route Handler以前作预先的处理。例以下面在请求到达route handler处理以前,经由Middleware的处理将请求的方法和地址打印在console中。数据库
var app = express(); app.use(function(req, res, next) { console.log('%s %s', req.method, req.url); next(); }); app.get('/', function(req, res, next) { res.send('Hello World!'); }); app.get('/help', function(req, res, next) { res.send('Nope.. nothing to see here'); });
固然这只是一个很是简单的例子,实际上express提供的Middleware能够实现很是强大的处理功能,例如对于session的管理等等。在具体本身动手写一个Middleware以前,不妨先去找找已经成熟的Middleware,毕竟express的社区是很是活跃的。express
req和res分别表明请求和响应的对象的直接引用,这个概念很是重要,可是暂时且放在一边,先来看第3个参数next。cookie
当调用next的时候,express将执行下一个Middleware。为何不能像通常的js函数同样执行完毕就进入下一个Middleware,而要经由next来实现呢?
这是由于Middleware中有可能会执行异步的操做(例如对数据库的读写等等),因此并不是到达函数底部就表明Middleware执行的完成,而应该将异步的操做完成才视做整个Middleware处理的完成。因为express并不知道操做什么时候算是完成,所以必须等到next函数被显性的呼叫以后,才会进入下一个Middleware的处理。
若是忘记调用next(),则会致使请求没法继续进行处理的错误。(固然,若是执行res.end又是另当别论的事情了)session
一、Middleware的顺序很是重要。
Middleware是按照顺序调用,所以若是调用的顺序不当极可能出现错误。另外若是将Route handler与Middleware混用,会致使在middleware之上部分的route不会执行这个middleware的内容。例以下面的代码中,向根节点的get请求就不会经由Middleware进行处理。app
app.get('/', function(req, res) { res.send('hello'); }); app.use(function(req, res, next) { next(); }); app.post('/', function(req, res) { res.send('bye'); });
另外一个更为常见的例子是static file server这个Middleware,由于咱们没法为每个资源文件,例如js,css写单独的routing,这个Middleware能够实现到指定的文件夹下寻找对应的文件,一旦找到对应的文件则会返回这个文件。若是将这个操做放在全部session处理的Middleware以前,则返回的文件不会请求新的session,可能会致使cookie设置不上。所以习惯性的将这个Middleware放在全部的Middleware以后使用。
二、忘记调用Next()
三、Req和Res都是对对象的直接引用。任何添加、删除、覆盖的操做都会由于它们是对对象的引用而反映到下一个Middleware以及以后route handler中。异步
Express4.x对于Middleware的功能进行了一些加强,同时将大部分原来默认搭载的Middleware移除,仅保留了最核心的Routing功能。进一步了解Express3.x到4.x的异同,参见《Express 4.x的特性和3.x的迁移》函数
参考文章:
《Express.js Middleware Demystified》
https://blog.safaribooksonline.com/2014/03/10/express-js-middleware-demystified/
post