Skip to content

路由

路由由 HTTP 方法、路径和一个或多个处理函数组成。app.METHOD() 仅匹配对应请求方法,app.all() 匹配任意方法,app.use() 用于挂载中间件或路由器。

路由参数

来源访问方式示例
路径参数req.params/users/:idreq.params.id
查询参数req.query/users?page=1req.query.page
请求体req.body需要先注册对应解析中间件。
请求头req.get(name)req.headersreq.get('authorization')
js
app.use(express.json())
app.use(express.urlencoded({ extended: false }))

app.post('/users/:id', (req, res) => {
  const { id } = req.params
  const { page } = req.query
  const { name } = req.body

  res.status(200).json({ id, page, name })
})

express.json() 仅解析 application/jsonexpress.urlencoded() 解析表单编码数据;二者都不处理 multipart/form-data 文件上传。

响应

路由处理函数必须发送响应或调用 next(),否则请求会一直挂起。

js
app.get('/users/:id', (req, res) => {
  const user = findUser(req.params.id)

  if (!user) {
    return res.status(404).json({ message: '用户不存在' })
  }

  res.set('Cache-Control', 'no-store').json(user)
})

常用方法:

  • res.status(code):设置状态码;通常与发送方法链式调用。
  • res.json(data)res.send(data):发送响应体。
  • res.sendStatus(code):发送状态码及其默认文本。
  • res.redirect([status,] url):重定向。
  • res.sendFile(path)res.download(path):发送或下载文件。

多处理函数与 next('route')

同一路由可注册多个处理函数。前一个处理函数调用 next() 后,控制权移交给下一个处理函数;next('route') 会跳过当前路由剩余处理函数,继续匹配后续同路径路由。

js
app.get(
  '/users/:id',
  (req, res, next) => {
    if (req.params.id === 'me') return next('route')
    next()
  },
  (req, res) => res.json({ id: req.params.id }),
)

app.get('/users/me', (req, res) => {
  res.json({ id: 'current-user' })
})

app.route()

将同一路径的不同方法集中声明,避免重复路径。

js
app
  .route('/articles/:id')
  .get((req, res) => res.json({ id: req.params.id }))
  .put((req, res) => res.sendStatus(204))
  .delete((req, res) => res.sendStatus(204))

express.Router()

Router 是可挂载的路由和中间件容器。路由模块只关心相对路径,挂载点由应用决定。

js
// routes/users.js
import { Router } from 'express'

const router = Router()

router.get('/', (req, res) => res.json([]))
router.get('/:id', (req, res) => res.json({ id: req.params.id }))

export default router
js
// app.js
import usersRouter from './routes/users.js'

app.use('/api/users', usersRouter)

基于 MIT 许可发布