https://www.cnblogs.com/zapple/p/5683016.html
强调几点:
An Express application is essentially a stack of middleware which are executed serially.(express应用其实就是由一系列顺序执行的Middleware组成。)
A middleware is a function with access to the request object (req), the response object (res), and the next middleware in line in the request-response cycle of an Express application. It is commonly denoted by a variable named next. Each middleware has the capacity to execute any code, make changes to the request and the reponse object, end the request-response cycle, and call the next middleware in the stack. Since middleware are execute serially, their order of inclusion is important.
If the current middleware is not ending the request-response cycle, it is important to call next() to pass on the control to the next middleware, else the request will be left hanging.
With an optional mount path, middleware can be loaded at the application level or at the router level. Also, a series of middleware functions can be loaded together, creating a sub-stack of middleware system at a mount point.
1、express的路由和中间件本质上都是对某个url路径的req和res和进行处理的函数,原型如下:
function (req, res, next)
二者甚至可以混用,例如4.x脚手架工具生成的代码中,把router对象作为中间件使用,这时router只处理中间件绑定路径中匹配的子路径(且请求方式符合相应的Http方法)。
区别在于,路由一般是针对常见的HTTP方法,如get、post等,中间件则不区分方法,只针对url处理,默认是处理根路径。并且,路由只处理完全匹配的url,中间件会处理匹配的url及其子路径。
二者的回调函数都可以决定是返回响应(req.end或req.send等api),或者调用next指定下一个回调,不可以既不返回,又不next(会造成该请求暂停,前端页面显示无响应)。
二者的执行顺序都是按编写的顺序。
express对象可以针对常见的HTTP方法指定路由,url路径可以是正则表达式:
app.METHOD(path, callback [, callback ...])
app.get('/example/c', [cb0, cb1, cb2]);
app.get('/example/c', function(), function());
如果指定多个callback,则构成路由句柄,可以调用next略过该句柄的剩余回调。
2、静态服务器
app.use(express.static(path.join(__dirname, 'public')));
这行代码将HelloExpress目录下的public目录作为静态文件交给static中间件来处理,对应的HTTP URI为“/”。static方法还可以设置options指定缓存时间等。
app.use('/static', express.static(path.join(__dirname, 'public')));
上面的代码呢,针对/static路径使用static中间件处理public目录。
3、Router对象
Express还提供了一个叫做Router的对象,行为很像中间件,你可以把Router直接传递给app.use,像使用中间件那样使用Router。另外你还可以使用router来处理针对GET、POST等的路由,也可以用它来添加中间件,总之你可以将Router看作一个微缩版的app。
创建一个Router实例,然后你就可以像使用app一样使用router,4.x脚手架工具生成的代码中,把router对象作为中间件使用:
var express = require('express');
var router = express.Router([options]);
router.get('/events', function(req, res, next) {
// ..
});
// invoked for any requests passed to this router
router.use(function(req, res, next) {
// .. some logic here .. like any other middleware
next();
});
module.exports = router;
下面是app.js里引用到index.js的代码:
var routes = require('./routes/index');
...
app.use('/', routes);
这里把路由挂载到了根路径下,注意要先匹配上层中间件的路径,才有机会匹配下层路由路径。