主题
路由
路由由 HTTP 方法、路径和一个或多个处理函数组成。app.METHOD() 仅匹配对应请求方法,app.all() 匹配任意方法,app.use() 用于挂载中间件或路由器。
路由参数
| 来源 | 访问方式 | 示例 |
|---|---|---|
| 路径参数 | req.params | /users/:id → req.params.id |
| 查询参数 | req.query | /users?page=1 → req.query.page |
| 请求体 | req.body | 需要先注册对应解析中间件。 |
| 请求头 | req.get(name)、req.headers | req.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/json,express.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 routerjs
// app.js
import usersRouter from './routes/users.js'
app.use('/api/users', usersRouter)