中间件是一种功能的封装方式,具体来说就是封装在程序中处理HTTP请求的功能。
中间件有3个参数:请求对象,相应对象,next函数。(错误处理有4个参数)。
中间件是在管道中执行的。在Express中,通过调用app.use向管道中插入中间件。
在管道的最后放一个“捕获一切”请求的处理器是常见的做法,由它来处理跟前面其他所有路由都不匹配的请求。这个中间件一般会返回状态码404。
如果不调用next(),请求就在那个中间件中停止了。
重点:
* 路由处理器(app.get、app.post)可以被看作只处理特定HTTP谓词(GET、POST)的中间件。
* 路由处理器的第一个参数必须是路径。
* 路由处理器和中间件的参数中都有回调函数。回调函数有3个或4个参数。3个参数:请求对象、响应对象、next函数;4个参数时变成了错误处理中间件:第一个参数变成了错误对象,另外3个依次。
* 如果不调用next(),管道就会被终止,应该发送一个相应到客户端(res.send、res.json、res.render)
* 如果调用了next(),一般不宜再发送响应到客户端。
var app = require('express')();
app.use(function(req, res, next){
console.log('\n\nALLWAYS');
next();
});
app.get('/a', function(req, res){
console.log('/a: 路由终止 ');
res.send('a');
});
app.get('/a', function(req, res){
console.log('/a: 永远不会调用 ');
});
app.get('/b', function(req, res, next){
console.log('/b: 路由未终止 ');
next();
});
app.use(function(req, res, next){
console.log('SOMETIMES');
next();
});
app.get('/b', function(req, res, next){
console.log('/b (part 2): 抛出错误 ' );
throw new Error('b 失败 ');
});
app.use('/b', function(err, req, res, next){
console.log('/b 检测到错误并传递 ');
next(err);
});
app.get('/c', function(err, req){
console.log('/c: 抛出错误 ');
throw new Error('c 失败 ');
});
app.use('/c', function(err, req, res, next){
console.log('/c: 检测到错误但不传递 ');
next();
});
app.use(function(err, req, res, next){
console.log(' 检测到未处理的错误 : ' + err.message);
res.send('500 - 服务器错误 ');
});
app.use(function(req, res){
console.log(' 未处理的路由 ');
res.send('404 - 未找到 ');
});
app.listen(3000, function(){
console.log(' 监听端口 3000');
});
中间件必须是一个函数。
10.1 常用中间件
connect最基础中间件
npm install --save connect
var connect = require(connect);
- basicAuth
app.use(connect.basicAuth)();
提供基本的访问授权。
*body-parser
npm install --save body-parser
app.use(require(body-parser)();)
只连入json和urlencoded的便利中间件。
- json(参见body-parser)
解析JSON编码的请求体。
*urlencoded(参见body-parser)
解析互联网媒体类型为application/x-www-form-urlencoded的请求体。这是处理表单和AJAX请求最常用的方式。
*multipart(已废弃)
*compress
app.use(connect.compress);
用gzip压缩响应数据。
*cookie-parser
npm install --save cookie-parser
app.use(require(cookie-parser)(秘钥));
提供对cookie的支持
- cookie-session
npm install --save cookie-session
app.use(require(cookie-session)());
提供cookie存储的会话支持。不支持。
- express-session
npm install --save express-session
app.use(require(express-session)());
提供会话ID(存在cookie里)的会话支持。
- csurf
npm install --save csurf
app.use(require(csurf)());
防范跨域请求伪造(CSRF)攻击。
- directory
app.use(connect.directory());
提供静态文件的目录清单支持。
- errorhandler
npm install --save errorhandler
app.use(require(errorhandler)());
为客户端提供栈追踪和错误消息。
*static-favicon
npm install --save static-favicon
app.use(require(static-favicon)(path_to_favicon));
提供favicon(出现在浏览器标题栏上的图标)。这个中间件不是必需的,可以简单地在static目录下放一个favicon.ico。
- morgan
npm install --save morgan
app.use(require(morgan)());
提供自动日志记录支持:所有请求都会被记录。
- method-override
npm install --save method-override
app.use(require(method-override)());
提供对 x-http-method-override 请求头的支持,允许浏览器“假装”使用除 GET 和 POST之外的 HTTP 方法。这对调试有帮助。只在编写 API 时才需要。
query
解析查询字符串,并将其变成请求对象上的 query 属性。这个中间件是由 Express 隐含连入的,所以不要自己连入它。response-time
npm install --save response-time
app.use(require(response-time)());
向响应中添加 X-Response-Time 头,提供以毫秒为单位的响应时间。一般在做性能调优时才需要这个中间件。
- static
app.use(express.static(path_to_static_files)());
提供对静态(public)文件的支持。这个中间件可以连入多次,并可指定不同的目录。
- vhost
npm install --save vhost
var vhost = require(vhost);
虚拟主机(vhost),它可使子域名在 Express 中更容易管
理。
10.2 第三方中间件
用 npm 搜索“Express”“Connect”和“Middleware”,会得到
一个相当不错的清单