app.param([name], callback)
给路由参数添加回调触发器,这里的name是参数名或者参数数组,function是回调方法。回调方法的参数按序是请求对象,响应对象,下个中间件,参数值和参数名。
如果name是数组,会按照各个参数在数组中被声明的顺序将回调触发器注册下来。还有,对于除了最后一个参数的其他参数,在他们的回调中调用next()来调用下个声明参数的回调。对于最后一个参数,在回调中调用next()将调用位于当前处理路由中的下一个中间件,如果name只是一个string那就和它是一样的(就是说只有一个参数,那么就是最后一个参数,和数组中最后一个参数是一样的)。
例如,当:user出现在路由路径中,你可以映射用户加载的逻辑处理来自动提供req.user给这个路由,或者对输入的参数进行验证。
app.param('user', function(req, res, next, id) {User.find(id, function(error, user) {if (err) {next(err);}else if (user){req.user = user;} else {next(new Error('failed to load user'));}});});
对于Param的回调定义的路由来说,他们是局部的。它们不会被挂载的app或者路由继承。所以,定义在app上的Param回调只有是在app上的路由具有这个路由参数时才起作用。
在定义param的路由上,param回调都是第一个被调用的,它们在一个请求-响应循环中都会被调用一次并且只有一次,即使多个路由都匹配,如下面的例子:
app.param('id', function(req, res, next, id) {console.log('CALLED ONLY ONCE');next();});app.get('/user/:id', function(req, res, next) {console.log('although this matches');next();});app.get('/user/:id', function(req, res) {console.log('and this mathces too');res.end();});
当GET /user/42,得到下面的结果:
CALLED ONLY ONCEalthough this matchesand this matches too
app.param(['id', 'page'], function(req, res, next, value) {console.log('CALLED ONLY ONCE with', value);next();});app.get('/user/:id/:page', function(req. res, next) {console.log('although this matches');next();});app.get('/user/:id/:page', function (req, res, next) {console.log('and this matches too');res.end();});
当执行GET /user/42/3,结果如下:
CALLED ONLY ONCE with 42CALLED ONLY ONCE with 3although this matchesand this mathes too
下面章节描述的
app.param(callback)在v4.11.0之后被弃用。
通过只传递一个回调参数给app.param(name, callback)方法,app.param(naem, callback)方法的行为将被完全改变。这个回调参数是关于app.param(name, callback)该具有怎样的行为的一个自定义方法,这个方法必须接受两个参数并且返回一个中间件。
这个回调的第一个参数就是需要捕获的url的参数名,第二个参数可以是任一的JavaScript对象,其可能在实现返回一个中间件时被使用。
这个回调方法返回的中间件决定了当URL中包含这个参数时所采取的行为。
在下面的例子中,app.param(name, callback)参数签名被修改成了app.param(name, accessId)。替换接受一个参数名和回调,app.param()现在接受一个参数名和一个数字。
var express = require('express');var app = express();app.param(function(param, option){return function(req, res, next, val) {if (val == option) {next();}else {res.sendStatus(403);}}});app.param('id', 1337);app.get('/user/:id', function(req, res) {res.send('Ok');});app.listen(3000, function() {console.log('Ready');});
在这个例子中,app.param(name, callback)参数签名保持和原来一样,但是替换成了一个中间件,定义了一个自定义的数据类型检测方法来检测user id的类型正确性。
app.param(function(param, validator) {return function(req, res, next, val) {if (validator(val)) {next();}else {res.sendStatus(403);}}});app.param('id', function(candidate) {return !isNaN(parseFloat(candidate)) && isFinite(candidate);});
在使用正则表达式来,不要使用
.。例如,你不能使用/user-.+/来捕获user-gami,用使用[\\s\\S]或者[\\w\\>W]来代替(正如/user-[\\s\\S]+/)。
//captures '1-a_6' but not '543-azser-sder'router.get('/[0-9]+-[[\\w]]*', function);//captures '1-a_6' and '543-az(ser"-sder' but not '5-a s'router.get('/[0-9]+-[[\\S]]*', function);//captures all (equivalent to '.*')router.get('[[\\s\\S]]*', function);
