app.get('/user/:id/edit', loadUser, andRestrictToSelf, function(req, res){
res.send('Editing user ' + req.user.name);
});
时刻铭记路由只是简单的函数,如下所示,我们可以定义返回中间件的函数以创建一个更具表现力,更灵活的方案。
复制代码 代码如下:
function andRestrictTo(role) {
return function(req, res, next) {
req.authenticatedUser.role == role
? next()
: next(new Error('Unauthorized'));
}
}
app.del('/user/:id', loadUser, andRestrictTo('admin'), function(req, res){
res.send('Deleted user ' + req.user.name);
});
常用的中间件“堆栈”可以通过一个数组来传递(会被递归应用),这些中间件可以混着、匹配到任何层次(which can be mixed and matched to any degree)。
复制代码 代码如下:
var a = [middleware1, middleware2]
, b = [middleware3, middleware4]
, all = [a, b];
app.get('/foo', a, function(){});
app.get('/bar', a, function(){});
app.get('https://www.jb51.net/', a, middleware3, middleware4, function(){});
app.get('https://www.jb51.net/', a, b, function(){});
app.get('https://www.jb51.net/', all, function(){});
对于这个实例的完整代码,请看 route middleware example 这个仓库。
我们可能会有多次想要“跳过”剩余的路由中间件,继续匹配后续的路由。做到这点,我们只需调用 next() 时带上 'route' 字符串 —— next('route')。如果没有余下的路由匹配到请求的 URL,Express 将会返回 404 Not Found。
十一、HTTP 方法
至此已接触了好几次 app.get(),除此这外 Express 还提供了其他常见的 HTTP 动作,如 app.post() 、app.del() 等等。
POST 用法的一个常用例子是提交一个表单。下面我们简单地在 html 中把表单的 method 属性设置为 post,控制权将会指派给它下面所定义的路由。
复制代码 代码如下:
<form method="post" action="https://www.jb51.net/">
<input type="text" />
<input type="text" />
<input type="submit" value="Submit" />
</form>
默认上 Express 并不知道如何处理这个请求的内容,因此我们必须添加 bodyParser 中间件,它将解析 application/x-www-form-urlencoded 和 application/json 请求的内容,并把变量存放于 req.body 中。我们可以像下述示例一样来使用这个中间件:
复制代码 代码如下:
app.use(express.bodyParser());
如下,我们的路由将有权访问 req.body.user 对象,当有 name 和 email 被定义时它将包含这两个属性(译注:如果表单发送的内容不为空的话)。
复制代码 代码如下:
app.post('https://www.jb51.net/', function(req, res){
console.log(req.body.user);
res.redirect('back');
});
当想在一个表单中使用像 PUT 这样的方法,我们可以使用一个命名为 _method 的 hidden input,它可以用以修改 HTTP 方法。为了做这个,我们首先需要 methodOverride 中间件,它必须出现于 bodyParser 后面,以便使用它的 req.body中所包含的表单值。
复制代码 代码如下:
app.use(express.bodyParser());
app.use(express.methodOverride());
对于这些方法为何不是默认拥有,简单来说只是因为它并不是 Express 所要求完整功能所必须。方法的使用依赖于你的应用,你可能并不需要它们,客户端依然能使用像 PUT 和 DELETE 这样的方法,你可以直接使用它们,因为 methodOverride 为 form 提供了一个非常不错的解决方案。下面将示范如何使用 PUT 这个方法,看起来可能像:
复制代码 代码如下:
<form method="post" action="https://www.jb51.net/">
<input type="hidden" value="put" />
<input type="text" />
<input type="text" />
<input type="submit" value="Submit" />
</form>
app.put('https://www.jb51.net/', function(){
console.log(req.body.user);
res.redirect('back');
});
十二、错误处理
Express 提供了 app.error() 方法以便接收到的异常在一个路由里抛出,或者传到 next(err) 中。下面这个例子将基于特定的 NotFound 异常处理不同的页面:
复制代码 代码如下:
function NotFound(msg){
this.name = 'NotFound';
Error.call(this, msg);
Error.captureStackTrace(this, arguments.callee);
}
NotFound.prototype.__proto__ = Error.prototype;
app.get('/404', function(req, res){
throw new NotFound;
});