服务器端路由是指:服务器端根据客户端请求的不同路径、http方法来执行不同的处理逻辑。
静态路由配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| const express = require('express')
const server = express()
server.get('/', (req, res) => { res.send('hello') })
server.get('/about', (req, res) => { res.send('about') })
const port = 3333
server.listen(port, () => { console.log('server started on port 3333') })
|
动态路由配置
动态路由是指:路径中带有参数的路由。
在express中,可以使用:param
来定义动态参数。
1 2 3 4 5 6
| server.get('/user/:userId', (req, res) => { const userId = req.params.userId
})
|
模块化管理路由
一般不会将路由直接写在server中,可以将所有的路由划分模块,然后引入。
创建模块化路由的步骤
- 创建路由模块文件。
- 调用
express.Router()
创建路由对象。
- 在路由对象上挂载具体的路由。
- 使用
module.exports
向外共享路由对象。
- 使用
server.use()
注册路由模块。
代码实例,先创建路由模块,比如这里创建了user相关的两个路由:
userRouter1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const express = require('express')
const router = express.Router()
router.get('/user/list', (req, res) => {
})
router.post('/user/add', (req, res) => {
})
module.exports = router
|
在创建server的文件中导入上面的模块:
1 2 3 4 5 6 7 8 9 10
| const express = require('express') const server = express()
const userRouter = require('./userRouter')
server.use(userRouter) server.listen(80, () => { console.log('server started on port 80') })
|
为模块添加前缀
1 2
| server.use('/api', userRouter)
|
路由中间件
除了静态路由和动态路由之外,还可以使用路由中间件来拦截路由并进行处理。
路由中间件是一个函数,它可以访问请求对象 (req)、响应对象 (res) 和应用中的下一个中间件函数 (next)。中间件函数可以执行各种任务,如修改请求和响应对象、执行身份验证、日志记录等。
1 2 3 4 5 6 7
| server.use((req, res, next) => { console.log('执行了中间件函数')
next() })
|
错误处理
下面定义了一个错误处理中间件,发生错误时会打印错误信息,向客户端返回一个500状态码和响应。
1 2 3 4 5
| server.use((err, req, res, next) => { console.error(err)
res.status(500).send('服务器错误') })
|
处理跨域
客户端在发送请求之前会先发送一个OPTIONS
请求,用于试探服务器是否能接受请求。如果服务端响应404、403、500就会停止继续请求。
下面的代码是处理这种情况的:
1 2 3 4 5 6 7 8 9 10 11 12
| server.all('*', (req, res, next) => { res.header('Access-Control-Allow-Origin', '*') res.header('Access-Control-Allow-Headers', 'Content-Type') res.header('Access-Control-Allow-Methods', '*') res.header('Content-Type', 'application/json;charset=utf-8')
if (req.method.toLowerCase() === 'options') { res.send(200) } else { next() } })
|
完整实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| const express = require('express') const server = express()
server.all('*', (req, res, next) => { res.header('Access-Control-Allow-Origin', '*') res.header('Access-Control-Allow-Headers', 'Content-Type') res.header('Access-Control-Allow-Methods', '*') res.header('Content-Type', 'application/json;charset=utf-8') if (req.method.toLowerCase() === 'options') { res.send(200) } else { next() } })
server.use((req, res, next) => { console.log('执行了中间件函数') next() })
server.get('/users/:userId/books/:bookId', (req, res) => { const userId = req.params.userId const bookId = req.params.bookId res.send(`User ID: ${userId}, Book ID: ${bookId}`) })
server.use((err, req, res, next) => { console.error(err.stack) res.status(500).send('服务器错误') })
server.listen(3333, () => { console.log('server started on port 3333') })
|