# router.param

为路由参数添加回调触发器,其中 name 为参数名称,callback 为回调函数。

# 概要

router.param(name, callback)

# 描述

为路由参数添加回调触发器,其中 name 为参数名称,callback 为回调函数。尽管 name 在技术上是可选的,但从 Express v4.11.0 开始不推荐使用此方法(见下文)。

回调函数的参数为​​:

  • req,请求对象。
  • res,响应对象。
  • next,表示下一个中间件函数。
  • name,参数的值。
  • 参数的名称。

app.param() 不同,router.param() 不接受路由参数数组。

例如,当 :user 出现在路由路径中时,您可以映射用户加载逻辑以自动将 req.user 提供给路由,或对参数输入执行验证。

router.param('user', (req, res, next, id) => {
  // try to get the user details from the User model and attach it to the request object
  User.find(id, (err, user) => {
    if (err) {
      next(err)
    } else if (user) {
      req.user = user
      next()
    } else {
      next(new Error('failed to load user'))
    }
  })
})

参数回调函数在定义它们的路由上是本地的。它们不会被安装的应用程序或路由继承。因此,在 router上定义的参数回调将仅由在 router路由上定义的路由参数触发。

一个参数回调在请求-响应周期中只会被调用一次,即使该参数在多个路由中匹配,如下例所示。

router.param('id', (req, res, next, id) => {
  console.log('CALLED ONLY ONCE')
  next()
})

router.get('/user/:id', (req, res, next) => {
  console.log('although this matches')
  next()
})

router.get('/user/:id', (req, res) => {
  console.log('and this matches too')
  res.end()
})

GET /user/42上,打印以下内容:

CALLED ONLY ONCE
although this matches
and this matches too

以下部分描述了 router.param(callback),自 v4.11.0 起已弃用。

router.param(name, callback) 方法的行为可以通过只向 router.param() 传递一个函数来完全改变。这个函数是 router.param(name, callback) 应该如何表现的自定义实现——它接受两个参数并且必须返回一个中间件。

此函数的第一个参数是应捕获的 URL 参数的名称,第二个参数可以是任何可能用于返回中间件实现的 JavaScript 对象。

函数返回的中间件决定了捕获 URL 参数时发生的行为。

在此示例中,将 router.param(name, callback) 签名修改为 router.param(name, accessId)router.param() 现在将接受名称和号码,而不是接受名称和回调。

const express = require('express')
const app = express()
const router = express.Router()

// customizing the behavior of router.param()
router.param((param, option) => {
  return (req, res, next, val) => {
    if (val === option) {
      next()
    } else {
      res.sendStatus(403)
    }
  }
})

// using the customized router.param()
router.param('id', 1337)

// route to trigger the capture
router.get('/user/:id', (req, res) => {
  res.send('OK')
})

app.use(router)

app.listen(3000, () => {
  console.log('Ready')
})

在此示例中,router.param(name, callback)签名保持不变,但没有使用中间件回调,而是定义了自定义数据类型检查函数来验证用户 ID 的数据类型。

router.param((param, validator) => {
  return (req, res, next, val) => {
    if (validator(val)) {
      next()
    } else {
      res.sendStatus(403)
    }
  }
})

router.param('id', (candidate) => {
  return !isNaN(parseFloat(candidate)) && isFinite(candidate)
})
Last Updated: 6/17/2023, 6:57:19 PM