Express路由配置

Express路由配置

服务器端路由是指:服务器端根据客户端请求的不同路径、http方法来执行不同的处理逻辑。

静态路由配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 引入express
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

// 根据userId处理逻辑

})

模块化管理路由

一般不会将路由直接写在server中,可以将所有的路由划分模块,然后引入。

创建模块化路由的步骤

  1. 创建路由模块文件。
  2. 调用express.Router()创建路由对象。
  3. 在路由对象上挂载具体的路由。
  4. 使用module.exports向外共享路由对象。
  5. 使用server.use()注册路由模块。

代码实例,先创建路由模块,比如这里创建了user相关的两个路由:

userRouter
1
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) //让options尝试请求快速结束
} 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')
})

评论