阅读 155

Express路由和中间件(express中间件原理)

Express中的路由

image.png

路由的匹配过程

image.png

路由最简单的用法

image.png

//导入express模块
const express = require('express')
//创建web4
const app = express()
//挂载路由
app.get('/', (req, res) => [
    res.send(`请求成功!`)
])
app.post('/', (req, res) => {
    res.send('提交成功!')
})
//监听端口
app.listen(80, () => {
    console.log('Listener server running at http://127.0.0.1')
})复制代码

模块化路由

image.png

创建一个路由模块

const express = require('express')          //1.导入express
const router = express.Router()             //2.创建路由对象
router.get('/user/list', function (req, res) { //3.挂载获取用户列表的路由
    res.send('Get user list')
})
router.post('/user/add', function (req, res) { //4.挂载添加用户路由
    res.send('Add new user.')
})
module.exports = router                         //5.向外导出路由对象复制代码

导入路由模块创建web服务

const express = require('express')
const app = express()
//导入路由模块
const router = require('./02-1-模块化路由')
//注册路由模块

app.use(router)

app.listen(80, () => {
    console.log('listener server running at http://127.0.0.1')
})复制代码

给路由模块加前缀

app.use('/app', router)

image.png

中间件调用流程

image.png

image.png

中间件next()函数

image.png

const express = require('express')
const app = express()
//定义中间件
const mw = function (req, res, next) {
    console.log('最简单的中间件函数');
    next()
}
app.listen(80, () => {
    console.log('listen server running at http://127.0.0.1');
})复制代码

定义全局生效的中间件

image.png

const express = require('express')
const app = express()
//创建中间件
const mw = function (req, res, next) {
    console.log('这是一个最简单的中间件');
    next()
}
//全局生效的中间件
app.use(mw)
//定义路由
app.get('/', (req, res) => {
    console.log('调用了这个路由')
    res.send('请求成功!')
})
app.post('/user', (req, res) => {
    console.log('调用了这个路由')
    res.send('提交成功!')
})
app.listen(80, () => {
    console.log(`listen server running at http://127.0.0.1`);
})复制代码

定义全局中间件简化形式

const express = require('express')
const app = express()
//全局生效的简化中间件
app.use(function (req, res, next) {
    console.log('简化的中间件')
    next()
})
//定义路由
app.get('/', (req, res) => {
    console.log('路由被调用了!')
    res.send('请求成功!')
})
app.post('/user', (req, res) => {
    console.log('路由调用成功!')
    res.send('提交成功!')
})
app.listen(80, () => {
    console.log('listen server running at http://127.0.0.1');
})复制代码

image.png

中间件的作用

image.png

//我们想获取调用路由的时间
const express = require('express')
const app = express()
//定义全局中间件
//中间件的req和res与路由是共享的
app.use(function (req, res, next) {
    //定义当前请求的时间
    let time = Date.now()
    //将中间件挂载到req请求中
    req.timeNow = time
    next()
})
app.get('/', (req, res) => {
    console.log(`请求路由的时间` + req.timeNow)
    res.send('请求成功!')
})
app.post('/user', (req, res) => {
    console.log(('提交的时间' + req.timeNow));
    res.send('提交成功!')
})
//设置服务器端口
app.listen(80, () => {
    console.log('listen server running http://127.0.0.1');
})复制代码

image.png

定义多个全局中间件

image.png

const express = require('express')
const app = express()
//定义第一个全局中间件
app.use(function (req, res, next) {
    console.log('调用第一个中间件');
    next()
})
app.use(function (req, res, next) {
    console.log('调用了第2个全局中间件');
    next()
})
app.get('/', (req, res) => {
    res.send('Home page')
})
app.listen(80, () => {
    console.log('listen server running at http://127.0.0.1');
})复制代码

image.png

定义局部中间件

const express = require('express')
const app = express()
//定义中间件
let mw = function (req, res, next) {
    console.log('这是一个局部中间件');
    next()
}
//定义路由这个调用了中间件
app.get('/user', mw, (req, res) => {
    res.send('第一个路由请求成功!')
})
//定义路由这个没调用中间件
app.get('/user/a', (req, res) => {
    res.send('第二个路由请求成功!')
})

app.listen(80, () => {
    console.log(`listen server running at http://127.0.0.1`)
})复制代码

路由调用局部中间件.gif

image.png

定义多个局部中间件

image.png

const express = require('express')
const app = express()
//定义中间件
let mw1 = (req, res, next) => {
    console.log('这是第一个局部中间件');
    next()
}
let mw2 = (req, res, next) => {
    console.log('这是第二个局部中间件');
    next()
}
//定义路由这个调用了中间件
app.get('/user', mw1, mw2, (req, res) => {
    res.send('第一个路由请求成功!')
})
//用数组形式调用两个局部中间件
/* app.get('/user', [mw1, mw2], (req, res) => {
    res.send('第一个路由请求成功!')
}) */
//定义路由这个没调用中间件
app.get('/user/a', (req, res) => {
    res.send('第二个路由请求成功!')
})

app.listen(80, () => {
    console.log(`listen server running at http://127.0.0.1`)
})复制代码

中间件的5个注意事项

  1. 一定要在路由之前注册中间件

  2. 客户端发送过来的请求,可以连续调用多个中间件进行处理

  3. 执行完中间件的业务代码之后,不要忘记调用next()函数

  4. 为了防止代码逻辑混乱,调用next()函数后不要再额外写代码

  5. 连续调用多个中间件,多个中间件之间,共享req和res对象

中间件的分类

image.png

应用级别中间件

image.png

路由级别中间件

image.png

错误级别中间件

image.png

image.png

image.png

注意:错误级别的中间件必须写在路由后面

image.png

Express内置中间件

通过express.json()获取json数据

image.png

image.png

image.png

const express = require('express')
//创建web实例
const app = express()
//挂载全局express.json()中间件处理传入的json对象
app.use(express.json())
//创建路由
app.post('/', (req, res) => {
    res.send(req.body)
    console.log(req.body)
})

app.listen(80, (req, res) => {
    console.log('listen server running at http://127.0.0.1');
})复制代码

通过express.urlencoded()这个中间件,来解析表单中的url-encoded格式的数据

image.png

image.png

第三方中间件使用步骤

image.png

image.png

image.png

指定义中间件

监听req的data事件和end事件

image.png

image.png

const express = require('express')
const app = express()
//这是解析表单数据的中间件
app.use((req, res, next) => {
    //定义中间件的业务逻辑
    // 定义一个str字符串,专门用来存储客户端发送过来的请求体数据
    let str = ''
    // 监听req打data事件
    req.on('data', (chunk) => {
        str += chunk
    })
    // 监听req的end事件
    req.on('end', () => {
        console.log(str);
        // 把字符串格式的请求体数据,解析成对象格式
    })
})
app.listen(80, () => {
    console.log('http://127.0.0.1');
})复制代码

image.png

将解析的body挂载到req.body中

image.png

const express = require('express')
//导入querystring模块
const qs = require('querystring')
const app = express()
//这是解析表单数据的中间件
app.use((req, res, next) => {
    //定义中间件的业务逻辑
    // 定义一个str字符串,专门用来存储客户端发送过来的请求体数据
    let str = ''
    // 监听req打data事件
    req.on('data', (chunk) => {
        str += chunk
    })
    // 监听req的end事件
    req.on('end', () => {
        // console.log(str);
        // 把字符串格式的请求体数据,解析成对象格式
        const body = qs.parse(str)
        // console.log(body);
        //将body挂载到req.body当中
        req.body = body
        next()
    })

})
app.post('/user', (req, res) => {
    console.log(req.body);
    res.send(req.body)
})
app.listen(80, () => {
    console.log('http://127.0.0.1');
})复制代码

自定义模块封装

image.png

image.png导入自定义模块

const parseObj = require('./16-自定义模块封装')
const express = require('express')
//导入querystring模块
const app = express()
//这是解析表单数据的中间件
app.use(parseObj)
app.post('/user', (req, res) => {
    console.log(req.body);
    res.send(req.body)
})
app.listen(80, () => {
    console.log('http://127.0.0.1');
})复制代码

暴露自定义模块

const qs = require('querystring')
let parseObj = (req, res, next) => {
    //定义中间件的业务逻辑
    // 定义一个str字符串,专门用来存储客户端发送过来的请求体数据
    let str = ''
    // 监听req打data事件
    req.on('data', (chunk) => {
        str += chunk
    })
    // 监听req的end事件
    req.on('end', () => {
        // console.log(str);
        // 把字符串格式的请求体数据,解析成对象格式
        const body = qs.parse(str)
        // console.log(body);
        //将body挂载到req.body当中
        req.body = body
        next()
    })

}
module.exports = parseObj复制代码

使用express写接口

接口

const express = require('express')
const app = express()
//配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false }))
//导入路由模块
const router = require('./17-router中间件')
//把路由模块,注册到app上
app.use('/api', router)
app.listen(80, () => {
    console.log('listen server running at http://127.0.0.1');
})复制代码

image.png没配置req.body为undefined //配置解析表单数据的中间件 app.use(express.urlencoded({ extended: false }))

router

const express = require('express')
const router = express.Router()
const app = express()


router.get('/get', (req, res) => {
    //通过req.query获取客户端通过查询字符串,发送到服务器的数据
    const query = req.query
    //调用res.send()方法,向客户端响应处理的结果
    res.send({
        status: 0,//0表示处理成功,1表示处理失败
        msg: 'Get请求成功!',//状态的描述
        data: query//需要响应给客户端的数据
    })
})
router.post('/post', (req, res) => {
    // 通过req.body获取请求体中包含的url-encoded个数的数据
    const body = req.body
    // 调用res.send()方法,向客户端响应结果
    console.log(body)
    res.send({
        status: 0,
        msg: 'post请求成功',
        data: body
    })
})
module.exports = router


作者:广交靓仔
链接:https://juejin.cn/post/7066230846918918175


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐