中间件的几个重要特性:
-
中间件必须是函数
// 情况一 app.use(static) // static必须是函数 // 情况二 app.use(static()) // static的返回值必须是函数
-
表示所有路由
// 省略路由字符串参数 app.use(中间件) // '/*' app.use('/*', 中间件)
-
顺序:再express4.0中,根据路由条件是否满足,中间件和路由时从上到下,一个一个执行。而在express4.0之前,必须显示的把路由连起来。
-
如果一个中间件既不使用next()使路由跳转到下一个中间件,也不响应数据给客户端,请求就会挂起,导致超时
-
在前面的例子中,我们的中间件会用语句return next()提前终止。Express不期望中间件返回值(并且它不会用返回值做任何事情),所以这只是缩短了的next(); return
目前就知道 return next() 等效于 next()。至于还有什么别的功能还不清楚
路由中间件
app.use(function(req, res, next){ // 0
console.log('\n\nALLWAYS');
next();
});
app.get('/a', function(req, res){ // 1
console.log('/a: 路由终止’);
res.send('a');
});
app.get('/a', function(req, res){ // 2
console.log('/a: 永远不会调用’);
});
app.get('/b', function(req, res, next){ // 3
console.log('/b: 路由未终止’);
next();
});
app.use(function(req, res, next){ // 4
console.log('SOMETIMES');
next();
});
app.get('/b', function(req, res, next){ // 5
console.log('/b (part 2): 抛出错误’ );
throw new Error('b失败’);
});
app.use('/b', function(err, req, res, next){ // 6
console.log('/b检测到错误并传递’);
next(err);
});
app.get('/c', function(err, req){ // 7
console.log('/c: 抛出错误’);
throw new Error('c失败’);
});
app.use('/c', function(err, req, res, next){ // 8
console.log('/c: 检测到错误但不传递’);
next();
});
app.use(function(err, req, res, next){ // 9
console.log(’检测到未处理的错误: ' + err.message);
res.send('500- 服务器错误’);
});
app.use(function(req, res){ // 10
console.log(’未处理的路由’);
res.send('404- 未找到’);
});
app.listen(3000, function(){ // 11
console.log(’监听端口3000');
});
访问/a
的路由后台打印结果:会执行 0 和 1, 2不会执行。因为1已经响应数据给客户端了
访问/b
: 会执行3 、4、5、6、9。 这里的throw new Error('b失败’)
就相当于next(),将请求传递给下一个路由中间件,并且通过err可以捕获到抛出的错误
访问/c
: 会执行7、8、10。注意这里不会执行9,因为在步骤8的时候并没有将搓搓传到下一个路由中间件,路由就不会到到9,而是直接到10了。
疑问:手动抛出错误跟服务本身出错有什么区别,服务器本身出错就会直接到抛出错误的路由。另外还可以手动定制500页面-也就是说,即使服务器出错也可以返回一定的页面给用户
自定义中间件
// /lib/tourRequiresWaiver.js
module.exports = {
tourRequiresWaiver: function(req, res, next){
res.type('text/plain')
next();
}
}
// 入口文件
const middleWaire = require('./lib/tourRequiresWaiver')
...
// 自定义中间件 --所有在它后面出现的路由都会调用这个中间件
app.use(middleWaire.tourRequiresWaiver)