Express4中文文档
给路由参数添加回调触发器,其中name
为参数名称或参数数组,callback
为回调函数。回调函数的参数依次是请求对象、响应对象、下一个中间件、参数的值和参数的名称。
如果 name
是一个数组,则为其中声明的每个参数注册 callback
触发器,按照它们的声明顺序。此外,对于除最后一个之外的每个声明的参数,在回调中调用 next
将为下一个声明的参数调用回调。对于最后一个参数,对 next
的调用将调用当前正在处理的路由的下一个中间件,就像 name
只是一个字符串一样。
例如,当 :user
出现在路由路径中时,您可以映射用户加载逻辑以自动将 req.user
提供给路由,或对参数输入执行验证。
app.param('user', function (req, res, next, id) {
// try to get the user details from the User model and attach it to the request object
User.find(id, function (err, user) {
if (err) {
next(err)
} else if (user) {
req.user = user
next()
} else {
next(new Error('failed to load user'))
}
})
})
参数回调函数在定义它们的路由器上是本地的。它们不会被安装的应用程序或路由器继承。因此,在 app
上定义的参数回调将仅由在 app
路由上定义的路由参数触发。
所有参数回调将在参数出现的任何路由的任何处理程序之前调用,并且它们在请求-响应周期中仅被调用一次,即使参数在多个路由中匹配,如下例所示。
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 matches too')
res.end()
})
在 GET /user/42
上,打印以下内容:
CALLED ONLY ONCE
although this matches
and 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) {
console.log('and this matches too')
res.end()
})
在 GET /user/42/3
上,打印以下内容:
CALLED ONLY ONCE with 42
CALLED ONLY ONCE with 3
although this matches
and this matches too
以下部分描述了
app.param(callback)
,自 v4.11.0 起已弃用。
app.param(name, callback)
方法的行为可以通过只向 app.param()
传递一个函数来完全改变。这个函数是 app.param(name, callback)
应该如何表现的自定义实现——它接受两个参数并且必须返回一个中间件。
此函数的第一个参数是应捕获的 URL 参数的名称,第二个参数可以是任何可能用于返回中间件实现的 JavaScript 对象。
函数返回的中间件决定了捕获 URL 参数时发生的行为。
在此示例中,将 app.param(name, callback)
签名修改为 app.param(name, accessId)
。app.param()
现在将接受名称和号码,而不是接受名称和回调。
var express = require('express')
var app = express()
// customizing the behavior of app.param()
app.param(function (param, option) {
return function (req, res, next, val) {
if (val === option) {
next()
} else {
next('route')
}
}
})
// using the customized app.param()
app.param('id', 1337)
// route to trigger the capture
app.get('/user/:id', function (req, res) {
res.send('OK')
})
app.listen(3000, function () {
console.log('Ready')
})
在此示例中,app.param(name, callback)
签名保持不变,但没有使用中间件回调,而是定义了自定义数据类型检查函数来验证用户 ID 的数据类型。
app.param(function (param, validator) {
return function (req, res, next, val) {
if (validator(val)) {
next()
} else {
next('route')
}
}
})
app.param('id', function (candidate) {
return !isNaN(parseFloat(candidate)) && isFinite(candidate)
})
'
.
' 字符不能用于捕获正则表达式中的字符。例如你不能使用'/user-.+/'
来捕获'users-gami'
,使用[\\s\\S]
或[\\w\\W]
代替(如在'/user-[\\s\\S]+/'
。例子:
// captures '1-a_6' but not '543-azser-sder' router.get('/[0-9]+-[[\\w]]*', function (req, res, next) { next() }) // captures '1-a_6' and '543-az(ser"-sder' but not '5-a s' router.get('/[0-9]+-[[\\S]]*', function (req, res, next) { next() }) // captures all (equivalent to '.*') router.get('[[\\s\\S]]*', function (req, res, next) { next() })