- 什么是中间件
- 中间件就是一个路由的处理函数,在参数列表中,有一个很重要的形参,叫做 next,只要这个函数的形参列表中,有一个next函数,他就是中间件。中间件的表现形式 function(req, res, next){ }
- 中间件表示每一个处理环节,这些处理环节,只负责单独的处理,每当上一个中间件处理完毕后,必须把处理的原材料,交给下一个中间件来继续处理;
- 中间件之间,共享的是 req 和 res 这两个对象;
- next 函数,只要一被调用,就会进入到下一个中间件的处理环节;
- 如何注册中间件:app.use(中间件的函数)
- 中间件里next函数的作用:从上一个中间件处理函数中,进入下一个中间件处理函数;
这是模拟中间件来记录客户端请求服务器时候的请求时间,请求的 URL地址,以及请求方式
const fs=require('fs')
const path=require('path')
//导入express模块
const express=require('express')
//创建express的服务器
const server=express();
//注册写入日志的中间件
server.use(writeLogs)
//请求根路径
server.get('/',(req,res)=>{
res.send('ok')
})
//调用 server.listen 方法,指定端口号并启动web服务器
server.listen(3000,()=>{
console.log('Express server running at http://127.0.0.1:3000')
})
//这是定义的写入日志的中间件
function writeLogs(req,res,next){
const info=`${new Date().toLocaleString()} ${req.url} ${req.method}\n`
fs.appendFile(path.join(__dirname,'./info.txt'),info,(err)=>{
if(err)throw err
console.log('写入日志成功')
// 当这个日志中间件,把信息记录好之后,需要调用next函数,让处理过程,进入到下一个处理环节
next()
})
}
这是模拟解析表单数据的中间件
文件夹如下:
03.parseFrom.js
const querystring = require('querystring')
// 定义一个 解析表单数据的中间件
function parseForm(req, res, next) {
let dataStr = ''
// 注意, data 事件,可能会触发多次,因此,每次拿到一小块的 chunk 数据,一定要拼接到 dataStr 上
req.on('data', (chunk) => {//chunk (片,块)是 Buffer 二进制类型的数据
// console.log(chunk)结果是<Buffer 6e 61 6d 65 3d 25 45 35 25 42 30 25 38 46 25 45 39 25 42 42 25 38 34 26 61 67 65 3d 31 38>
dataStr+=chunk
})
// 当触发 req 的 end 事件,就表示数据已经接收完毕了
req.on('end', () => {
// 得到的这个 result ,我们应该如何 传递给下一个中间件,或者如何传递给下一个路由呢?
//console.log(dataStr)结果是name=zhangsan&age=18
const result = querystring.parse(dataStr)//将字符串形式解析成对象形式
console.log(result)//{ name: 'zhangsan', age: '18' }
req.body = result//将result重新挂载到req上
next()
})
}
module.exports = parseForm
04.router.js
//导入express模块
const express = require('express')
//创建路由对象
const router = express.Router()
router.post('/api/postinfo', (req, res) => {
//console.log(req.body)
res.send('你提交的数据是: ' + JSON.stringify(req.body))
})
//导出路由对象
module.exports = router
02.模拟解析表单数据的中间件.js
方法一:使用 req.on(‘data’, (chunk)=>{})和req.on(‘end’, ()=>{}) 来获取表单,并使用 querystring模块的parse方法来解析成对象;
//导入express模块
const express = require('express')
//创建服务器
const server = express()
// 导入自己的解析表单数据的中间件
const parseForm = require('./03.parseForm.js')
// 注册 解析表单的中间件
server.use(parseForm)
//导入路由模块
const router = require('./04.router.js')
server.use(router)
server.listen(3000, () => {
console.log('http:127.0.0.1:3000')
})
方法二:使用第三方的body-parser中间件来解析表单;
//导入express模块
const express = require('express')
//创建服务器
const server = express()
// 1. 运行 `npm i body-parser ` 安装解析 表单数据的 body-parser 中间件
// 2. 导入中间件
const bodyParser = require('body-parser')
// 3. 注册中间件
// bodyParser.urlencoded({ extended: false }) // extended : false 表示,不使用扩展模块来解析表单数据,而是使用 Node 内置的 querystring 模块来解析表单数据;
// urlencoded 表示解析 普通的表单数据,解析 键值对形式的 数据
server.use(bodyParser.urlencoded({ extended: false }))
//导入路由模块
const router = require('./04.router.js')
server.use(router)
server.listen(3000, () => {
console.log('http:127.0.0.1:3000')
})
补充:Express 框架中对中间件的5种分类
- 应用级别中间件:挂载到 server 对象身上的 中间件(函数 )
- 路由级中间件: 挂载到 router 对象上的中间件
- 错误处理中间件:参数列表中要有四个形参,从前到后分别是 err, req, res, next
- 内置中间件: Express 中唯一的内置中间件 express.static(root, [options])
- 第三方中间件: 通过 npm安装的中间件,叫做 第三方中间件!