express中间件

  • Express 是一个自身功能极简,完全是由路由和中间件构成一个的 web 开发框架:从本质上来说,一个 Express 应用就是在调用各种中间件。

  • 中间件(Middleware) 是一个函数,它可以访问请求对象(request object (req)), 响应对象(response object (res)), 和 web 应用中处于请求-响应循环流程中的中间件,一般被命名为 next 的变量。

  • 中间件的功能包括:

    • 执行任何代码。
    • 修改请求和响应对象。
    • 终结请求-响应循环。
    • 调用堆栈中的下一个中间件。
  • 如果当前中间件没有终结请求-响应循环,则必须调用 next() 方法将控制权交给下一个中间件,否则请求就会挂起。

  • Express 应用可使用如下几种中间件:

    • 应用级中间件
    • 路由级中间件
    • 错误处理中间件
    • 内置中间件
    • 第三方中间件
  • 使用可选则挂载路径,可在应用级别或路由级别装载中间件。另外,你还可以同时装在一系列中间件函数,从而在一个挂载点上创建一个子中间件栈。

1.应用级中间件

  • 应用级中间件绑定到 app 对象 使用 app.use()app.METHOD(), 其中, METHOD 是需要处理的 HTTP 请求的方法,例如 GET, PUT, POST 等等,全部小写。

代码展示:

// express中间件 - 应用级别中间件
/*
我们已经知道,中间件其实就是一个回调函数,express框架中存在很多中间件
这里我们展示 应用级别中间件的使用
*/

/*
使用方法:
应用级中间件一般是绑定到app.use()或app.Method()(app.get,app.post)中来使用的,
里面传递两个参数('path' , 回调函数)其中,path为可选的
*/

// 1.引入 express框架
const express = require('express')
// 2.创建服务器
const app = express()

// 创建中间件
function addToken(req, res, next){
console.log('检查Token');
next()
}

// 1.全局注册中间件(不传入path参数),use后面所有的请求都要经过这个中间件
// app.use(addToken)//发送两个请求过后控制台输出两次"检查Token"(证明调用了两次中间件)

// 2.指定路径使用中间件(传入path参数),单独该路径才调用中间件
app.use('/login',addToken)//只有发送`/login`,是控制台才会出输出"检查Token"

// 发送请求
app.get('/' , (req,res)=>{
res.send('你好! home!')
})
app.get('/login' , (req,res)=>{
res.send('你好! login!')
})

// 监听端口
app.listen(3000 , ()=>{
console.log('服务器已启动! 端口3000正在监听...');
})

结果展示:

  • 全局调用(没有加入path参数)
    image

  • 指定调用(加入指定的path参数)
    image

2.路由级中间件

  • 路由级中间件和应用级中间件一样,只是它绑定的对象为 express.Router()

代码展示:

  • 创建路由(router.js)
// 创建路由
// 1.引入express框架
const express = require('express')
// 2.创建路由
const router = express.Router()

// 设置路由(二级请求url地址)
router.get('/' , (req,res)=>{
res.send('你好! 首页!!')
})
router.get('/home' , (req,res)=>{
res.send('你好! home!')
})
router.get('/login' , (req,res)=>{
res.send('你好! login!')
})

// 暴露路由
module.exports = router
  • 路由级中间件的调用(路由级别中间件.js)
// express中间件 - 路由级别中间件
// 路由级中间件和应用级中间件是非常相似的,只是它绑定的对象为 express.Router()。

// 1.引入 express框架
const express = require('express')
// 2.创建服务器
const app = express()
// 3.引入路由
const router = require('./router/router.js')

// 注册应用级别中间件(设置为全局引用)
app.use((req,res,next)=>{
console.log('验证Token');
next()
})

// 路由级别(控制一级匹配,先进入'/',在进入路由)
app.use('/api', router)

// 启动服务器
app.listen(3000 , ()=>{
console.log('服务器已启动! 端口3000正在监听...');
})

结果展示:

  • 浏览器中发送请求
    image

  • 终端中显示
    image

3.错误级中间件

  • 错误处理中间件和其他中间件定义类似,只是要使用 4 个参数,而不是 3 个,其签名如下: (err, req, res, next)
  • 一般写在前所有中间件的最后面,用于捕获整个项目的错误,防止程序崩溃

代码展示:

  • 这里就展示js文件,router是沿用上面的路由中间件的
// express中间件 - 错误级别中间件
/*
错误处理中间件和其他中间件定义类似,只是要使用 4 个参数,
而不是 3 个,其签名如下: (err, req, res, next)。
*/

// 1.引入 express框架
const express = require('express')
// 2.创建服务器
const app = express()
// 3.引入路由
const router = require('./router/router.js')

// 注册应用级别中间件(设置为全局引用)
app.use((req,res,next)=>{
console.log('验证Token');
next()
})

// 路由级别(控制一级匹配,先进入'/',在进入路由)
app.use('/api', router)

// 错误级别中间件(一般是放在中间件的最后面用于捕获项目中的错误)
app.use((err , req, res , next)=>{
// 捕获错误的时候首先要将状态码改为404或者500
console.log('???');
res.status(404).send('???')
})
// 启动服务器
app.listen(3000 , ()=>{
console.log('服务器已启动! 端口3000正在监听...');
})

结果展示:

  • 当访问到不存在的路由url时,就会在浏览器中报错,并且请求状态码为404

4.内置中间件

  • Express 4.16.0 版本开始,Express 内置了 3 个常用的中间件,极大的提高了 Express 项目的开发效率和体验

    • express.static 快速托管静态资源的内置中间件,例如: HTML 文件、图片、CSS 样式等(无兼容性)
    app.use(express.static('public'))//public表示目标文件夹的名字
    app.use(express.static('uploads'))//同上
    app.use(express.static('files'))//同上
    • express.json 解析 JSON 格式的请求体数据[post](有兼容性,仅在 4.16.0+ 版本中可用)

    • express.urlencoded 解析 URL-encoded 格式的请求体数据(有兼容性,仅在 4.16.0+ 版本中可用)其实多用于解析post请求参数的

基本使用

// 导入express模块
const express = require('express')
// 创建express的服务实例
const app= express()

// 注意:除了错误级别的中间件,其他的中间件,必须在路由之前进行配置
// 通过express.json()这个中间件,解析表单中的JSON格式的数据
app.use(express.json())
// 通过express.urlencoded()这个中间件,来解析表单中的url-encoded格式的数据
app.use(express.urlencoded({extended:false}))//其实就是解析post参数的

app.post('/user',(req,res)=>{
//在服务器,可以使用req.body这个属性,来接收客户端发过来的请求体数据
//默认情况下,如果不配置解析表单数据的中间件,则req.body默认等于undefined
console.log(req.body);
res.send('ok')
})

app.post('/book',(req,res)=>{
// 在服务器端,可以通过req.body来获取JSON格式的表单数据和url-encoded格式的数据
console.log(req.body);
res.send('okk')
})
// 调用app.listen方法,指定端口号并启动服务器
app.listen(80,(req,res)=>{
console.log('http://127.0.0.1');
})

static用法在后面的托管静态资源中会详细讲解

5.第三方中间件

  • 这个其实就是引用第三方的中间件而已,安装所需功能的 node 模块,并在应用中加载,可以在应用级加载,也可以在路由级加载。

实行流程

  1. 安装第三方中间件
$ npm i xxx
  1. 使用require导入中间件
  2. 调用app.use()注册并使用中间件