Express.js 应用-中间件的使用

 2016年03月09日    275     声明


在Express 的app.js文件中,可以向应用添加一些中间件。Express 的通过方法重载将中间件添加到应用中,这些中间件可以被其后路由中的GETPOST等HTTP方法使用,也可以通过中间件做一些通用的处理。


  1. Expres中的中间件
  2. 数据解析中间件
  3. 设置静态目录
  4. 通用处理

1. Expres中的中间件

Express 应用创建后,会默认添加几个中间件。在app.js中:

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

app.use(function(req, res, next) {
  // 设置所有HTTP请求的超时时间
  req.setTimeout(5000)
  // 设置所有HTTP请求的服务器响应超时时间
  res.setTimeout(5000)
  next();
});

/// catch 404 and forwarding to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

/// 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: {}
  });
});

module.exports = app;

app.js文件中,通过app.use()方法重载引入的都是中间件。所有中间件都是针对HTTP的处理,你可以在中间件中进行数据解析、设置静态目录、或是做一些通用的处理。


2. 数据解析中间件

在Express引入的中间中,有几个用于数据解的,如:

app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());

通过这些中间的处理,Express会将HTTP的请求中的参数和Cookie进行格式化,会将这些数据转换为对象形式。这样在其后的路由中,可以很容易的处理这些数据。


3. 设置静态目录

静态目录是在客户端可以不通过路由映射而直接访问的目录。如,在app.js中设置了public目录:

app.use(express.static(path.join(__dirname, 'public')));

public目录会被做为静态资源的根目录,这样在客户端我们就可以访问到public下的静态资源。

如,访问public/stylesheets/style.css样式文件,在客户端就可以像下面这样引用:

通过app.use()重载和express.static()方法,我们也可以设置其它的静态资源目录。

如,我们在Express的根目录下有一个存放上传文件的目录upload,我们要在客户端以静态资源的方式访问这个目录,可以像下面这样设置:

app.use(express.static(path.join(__dirname, 'upload')));


4. 通用处理

中间件还可以做一些通用的处理,在app.js中:

//捕获 404 状态并传递到错误处理中
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

/// 错误处理

// 开发环境下的错误处理
// 会输出堆栈信息
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
    });
  });
}

// 生产环境下的错误处理
// 不会向用户泄漏堆栈错误
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

在这些中间件中,对HTTP错误40450*等错误进行了处理,这样我们就可以统一处理所有应用异常。


中间件是针对HTTP请求的中间处理,在中间件中可以访问HTTP请求中的请求对象响应对象,也可以通过next回调函数将所做处理传递到其后的HTTP路由处理或其它中间件中:

// 通过中间件向req或res中添加一些处理
app.use(function(req, res, next) {
  // 向req中添加一个user对象
  req.user = {name:'myName'};
  // req.locals中添加一个site对象,在其后的路由处理中通过render渲染后的视图中都可以访问到这个对象
  req.locals.site = {name:'IT笔录', domain:'itbilu.com'};
  next();
});

// 访问上一个中间件中的数据
app.use(function(req, res, next) {
  /**
  * 中间件影响其后的中间件,我们可以在后面的中间件中访问请一个中间件的数据
  * 中间件也会影响其后的路由,在路由处理函数中同样也可以访问它前面中间件的数据
  */ 
  console.log(req.user)
  next();
});