开发过javaEE的童鞋一定知道filter,它是一个过滤器,可以拦截任何请求,可以对请求的request和response做相关处理。filter的一般形式是这样的:
public class MyFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
//do somthing here
filterChain.doFilter(request, response);
}
public void destroy() {
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}
...
<filter>
<filter-name>myFilter</filter-name>
<filter-class>com.test.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
Express中也有这种过滤器,但它叫中间件。跟filter不同的是,它是一个函数。它也可以访问请求对象(request object (req)), 响应对象(response object (res)), 和 web 应用中处于请求-响应循环流程中的中间件,一般被命名为 next 的变量。
Express中间件可分为五种:
- 应用级中间件
- 路由级中间件
- 错误处理中间件
- 内置中间件
- 第三方中间件
应用级中间件
即application级中间件,作用域贯穿整个application,application也就是Express的实例。
使用express-generator创建一个项目middleware:
express middleware
打开app.js,我们可以看到其中一段404的应用级中间件:
...
// 这个中间件没有指定uri,所以它可以拦截所有请求
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
...
应用级中间也可以指定范围,比如这样:
app.use(‘/users’, function(req, res, next) {
var err = new Error('User Not Found');
err.status = 404;
next(err);
});
app.use(‘/roles’, function(req, res, next) {
var err = new Error('Role Not Found');
err.status = 404;
next(err);
});
路由级中间件
路由级中间件与应用级相差无几,只是绑定的对象变成了express.Router的实例。
举个栗子, routes/index.js:
var express = require('express');
var router = express.Router();
router.use('/', function(req, res, next){
console.log('somebody visit the homepage');
});
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
错误处理中间件
普通中间件有三个参数,req、res和next,而错误处理中间件有4个参数,分别是err、req、res和next。
app.js有一段错误处理中间件的代码:
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
内置中间件
express.static 是 Express 唯一内置的中间件。
app.js中是这样使用的:
...
//设置express项目的静态目录是"/public"
app.use(express.static(path.join(__dirname, 'public')));
...
顾名思义,这是第三方提供的中间件,为express的功能提供补充。
第三方中间件可以注册为应用级中间件,也可以注册为路由级中间件。
仍然可以看app.js的代码片段:
...
//cookieParser是一个第三方中间件
var cookieParser = require('cookie-parser');
...
//将cookieParser注册为应用级中间件
app.use(cookieParser());
...