参考:http://expressjs.com/en/4x/api.html
express
自身是一个功能极简,完全是由路由和中间件构成的一个Web开发框架。 从本质上来说,一个express
应用就是在调用各种中间件和路由。
中间件(Middleware)是一个函数,它可以访问请求对象(request)、响应对象(response), 和Web应用中处于请求-响应流程中的中间件,一般被命名为next方法。
中间件函数原型是:function ([Object error, ] Object request, Object response, Function next)
。
error
对象是发生错误后的错误对象。
request
对象是请求相关的对象。
response
对象是响应相关的对象。
next
如果被调用了,表示下一个中间件会接着执行,如果没有调用,后面的中间件就不会被执行了。
这种设计在架构模式中称为分层模式,在设计模式中称为责任链模式。在其他Web开发框架中经常会设计拦截器,拦截器通常使用观察者模式实现。 这种实现方法比拦截器更具有通用性、灵活性大大增强。
应用级中间件绑定到app
对象,使用app.use()
或者app.METHOD()
方法,METHOD
是GET
、POST
、PUT
、DELETE
、HEAD
等HTTP
轻视方式,全部小写。
如果不把中间件挂载到指定的URL上,那么就是对所有的请求都有效,如果我们把此中间件的调用放在最前面(防止被终结), 就实现了全局拦截器的效果。
示例:
var express = require('express');
var app = express();
app.use(function (request, response, next) {
//TODO
next();
});
示例:
var express = require('express');
var app = express();
//other middleware invoked!
// catch 404 and forward to error handler
app.use(function (request, response, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
在express
中,404
并不被看作是一个错误。因此,错误处理器中间件并不捕获404
。 这是因为404
只是意味着某些功能没有实现。也就是说,express
执行了所有中间件、路由之后还是没有获取到任何输出。 你所需要做的就是在其他所有中间件的后面添加一个处理404
的中间件。
这个中间件看似与全局拦截器一样,不同的地方就在与他放的地方,全局拦截器放在所有调用中间件的最前面,这是为了防止某些中间件没有调用next()
方法而终止了后面的中间件。404
错误中间件要放在所有中间件的后面,这是因为一旦其他中间件不能正确处理,他才有机会得到执行,其他中间件能正确处理,他就不会被执行。
示例:
var express = require('express');
var app = express();
app.use('/index', function(request, response, next) {
//TODO
next();
});
指定URL上的拦截器。
示例1:
var express = require('express');
var app = express();
app.use(function (request, response, next) {
//TODO
next();
}
, function (request, response, next) {
//TODO
next();
}
);
这有什么作用呢?为啥不写在一块儿呢?这是因为项目开发过程中为了预防变化,而将功能拆分开,如果不需要,直接注释掉即可, 而不需要改来改去的!
示例2:
var express = require('express');
var app = express();
app.use('/index', function (request, response, next) {
//TODO
next();
}
, function (request, response, next) {
//TODO
next();
}
);
路由级中间件绑定到router
对象,使用router.use()
或者router.METHOD()
方法,METHOD
是GET
、POST
、PUT
、DELETE
、HEAD
等HTTP
轻视方式,全部小写。
示例:
var express = require('express');
var router = express.Router();
router.use(function (request, response, next) {
//TODO
next();
});
router.use('/index', function (request, response, next) {
//TODO
next();
});
router.get('/index', function (request, response, next) {
//TODO
next();
});
错误处理中间件有4个参数,定义错误处理中间件时必须使用这4个参数。即使不需要next方法,也必须在签名中声明它,否则中间件会被识别为一个常规中间件,不能处理错误。
示例:
var express = require('express');
var app = express();
app.use(function (error, request, response, next) {
res.status(error.status || 500);
if (app.get('env') === "development") {
res.render('error-development', { error: error });
} else {
res.render('error-production', { error: error });
}
});
从4.x
版本开始,express
已经不再依赖Connect
了。 除了express.static(),express
以前内置的中间件现在已经全部单独作为模块安装使用了。
示例:
var express = require('express');
var app = repress();
var options = {
dotfiles : 'ignore',
etag : false,
extensions: ['htm', 'html'],
index : false,
maxAge : '1d',
redirect : false,
setHeaders: function (response, path, stat) {
response.set('x-timestamp', Date.now());
}
};
app.use(express.static(path.join(__dirname, 'public'), options));
通过使用第三方中间件从而为express
应用增加更多功能。 安装所需功能的node
模块,并在应用中加载,可以在应用级加载,也可以在路由级加载。
下面是一些常用的第三方中间件:
req.user
属性访问被认证的用户对象。Cookie
头进行处理,然后通过req.cookies
属性来访问所有cookie对象示例:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var app = repress();
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
中间件函数原型是:function ([Object error, ] Object request, Object response, Function next)
。
我们自己编写一个node.js
模块,实现此函数即可,当然也可以直接使用匿名函数的方法。
示例(url-decode.js模块):
module.exports = function (request, response, next) {
request.url = decodeURI(request.url);
next();
};
然后调用(url-decode.js模块):
var express = require('express');
var app = express();
app.use('require(./url-decode.js)');
功能如此简单,我们可以直接写成如下,省去加载文件:
var express = require('express');
var app = express();
app.use(function (request, response, next) {
request.url = decodeURI(request.url);
next();
});
一定要注意调用顺序。