学什么都是这个样子
还没开始学就先退缩
是什么都学不会的。
携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 5 天,点击查看活动详情
-
Express 路由
路由指的是客户端的请求与服务器处理函数之间的映射关系, 由三部分组成, 分别是请求的类型、请求的 URL 地址、处理函数。
(1) 把路由挂载到app上(使用路由最简单的方式)
app.METHOD(PATH, HANDLER)
(2) 模块化路由,推荐路由抽离为单独的模块(方便管理)
① 创建路由模块对应的.js文件
② 调用 express.Router() 函数创建路由对象
③ 向路由对象上挂载具体的路由
④ 使用 module.exports 向外共享对象路由
⑤ 使用 app.use() 函数注册路由模块
var express = require('express') // 1. 导入 express
var router = express.Router() // 2. 创建路由对象
router.get('/user/list', function(req, res) { // 3. 挂载获取用户列表的路由
res.send('Get user list.')
})
router.post('/user/add', function(req, res) { // 3. 挂载添加用户的路由
res.send('Add new user.')
})
module.exports = router // 5. 向外导出路由对象
// 1. 导入路由模块
const userRouter = require('./router/user.js')
// 2. 使用 app.use() 注册路由模块
app.use(userRouter)
- 中间件
业务流程的中间处理环节。 Express的中间件本质上就是一个 function 处理函数。
// 与路由的区别,就在于next()函数,就相当于将处理后的结果传递下去,交给下一个中间件或路由
const mw = function('/', function(req, res, next) {
// 当前中间件的业务处理完毕后,必须调用 next() 函数
next()
})
定义全局的中间件时可以将中间件直接写入app.use()中。
需要多个处理逻辑时,可以连续定义多个全局中间件,会按照中间件定义的先后顺序依次进行调用。但是都必须调用next()函数。
app.use(function(req, res, next) { // 1. 第一个全局中间件
console.log('调用了第一个全局中间件')
next()
})
app.use(function(req, res, next) { // 1. 第二个全局中间件
console.log('调用了第二个全局中间件')
next()
})
app.get('/user', '中间件名称', (req, res) =>{ // 请求这个路由,会依次触发上述两个全局中间件
res.send('Home Page.')
})
多个中间之间,共享同一份 req 和 res。我们可以在上游的中间件中,统一为 req 或 res 对象添加自定义的属性或方法,供下游胡中间件或路由进行使用。
不使用 app.use() 定义的中间件,叫做局部生效的中间件
注意事项
一定要在路由之前注册中间件
客户端发送过来的请求,可以连续调用多个中间件进行处理
执行完中间件的业务代码之后,不要忘记调用 next() 函数
为了防止代码逻辑混乱,调用 need() 函数之后不要写额外的代码
连续调用多个中间件时,多个中间件之间,共享 req 和 res
- 中间件的分类
- 应用级别的中间件
通过 app.use() 或 app.get() 或 app.post(),绑定到 app 实例上的中间件
- 路由级别的中间件
绑定到 express.Router() 实例上的中间件, 叫做路由级别的中间件。与应用级别中间件的区别是,应用级别的中间件是绑定到 app 实例上,路由级别的中间件绑定到 router 实例上.
- 错误级别的中间件
错误级别的中间件的 function 处理函数中,必须有4个形参,形参顺序从前到后,分别是(err, req, res, next),
**错误级别的中间件是定义在路由后面的**.作用是专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃.(在路由中 throw 一个异常,可以在中间件中通过 err.message 中获取)
- Express 内置的中间件
express.static 快速托管静态资源的内置中间件(无兼容性)
express.json 解析 JSON 格式的请求体数据(有兼容性, 4.16.0+)
express.urlencoded 解析 URL-encoded 格式的请求体数据(有兼容性, 4.16.0+)
// 可以使用 req.body 这个属性来接收客户端发送过来的请求体数据
// 默认情况下,如果不配置解析表单数据中的中间件,则 req.body 默认等于 undefined
- 第三方的中间件
可以按需下载
在 express@4.16.0 之前的版本中使用 body-parser,来解析请求体数据,这个需要先安装
Express 内置的 express.urlencoded 就是基于body-parser 进一步封装出来的.
- 自定义中间件
① 定义中间件
② 监听 req 的 data 事件:
获取客户端发送到服务器的数据,如果数据量较大,则客户端会把数据切割后,分批发送到服务器.所以 data 事件可能会触发多次,每一次触发获取到的数据只是完整数据的一部分,需要手动拼接.
'let str='' req.on('data', (chunk) => {str += chunk})'
③ 监听 req 的 end 事件:
数据接收完毕后, 会自动触发 req 的 end 事件
'req.on('end', ( ) => { console.log(str) })'
④ 使用 querystring 模块解析请求体数据,这个模块提供的 parse() 函数,可以轻松把查询字符串解析成对象的格式
'const qs = require('querystring')'
'const body = qs.parse(str)'
⑤ 将解析出来的数据对象挂在为 req.body
'req.on('end', ( ) => { const body = qs.parse(str) req.body=body next() })'
⑥ 将自定义中间件封装为模块
'app.use()'