Express中间件的理解

中间件函数能够访问请求对象 (req)、响应对象 (res) 以及应用程序的请求/响应循环中的下一个中间件函数。下一个中间件函数通常由名为next的变量来表示。

中间件函数可以执行以下任务:

  • 执行任何代码。
  • 对请求和响应对象进行更改。
  • 结束请求/响应循环。
  • 调用堆栈中的下一个中间件函数。

如果当前中间件函数没有结束请求/响应循环,那么它必须调用next()函数,以将控制权传递给下一个中间件函数。否则,请求将保持挂起状态。

演示示例:

/**
 * express 中间件使用解析
 */

const express = require('express')

// 本次 http 请求的实例
const app = express()

// 模拟登陆验证
function loginCheckSuccess(req, res, next) {
  console.log('模拟登陆成功')
  setTimeout(() => {
    next()
  })
}

// 模拟登陆失败
function loginCheckFailed(req, res, next) {
  console.log('模拟登陆失败')
  setTimeout(() => {
    res.json({
      errno: -1,
      msg: '登陆失败'
    })
  })
}

app.use((req, res, next) => {
  console.log('请求开始···', req.method, req.url)
  next()
})

app.use((req, res, next) => {
  // 假设在处理 cookie
  req.cookie = {
    userID: 'abc123'
  }
  next()
})

app.use((req, res, next) => {
  // 假设处理 post data
  // 异步
  setTimeout(() => {
    req.body = {
      a: 100,
      b: 200
    }
    next()
  })
})

app.use('/api', (req, res, next) => {
  console.log('处理 /api 路由')
  next()
})

app.get('/api', (req, res, next) => {
  console.log('get /api 路由')
  next()
})

app.post('/api', (req, res, next) => {
  console.log('get /api 路由')
  next()
})

app.get('/api/get-cookie', loginCheckSuccess, (req, res, next) => {
  console.log('get /api/get-cookie')
  res.json({
    errno: 0,
    data: req.cookie 
  })
})

app.post('/api/get-post-deta', loginCheckFailed, (req, res, next) => {
  console.log('post /api/get-post-data')
  res.json({
    error: 0,
    data: res.body
  }) 
})

app.use((req, res, next) => {
  console.log('处理 404')
  res.json({
    error: -1,
    msg: '404 not found'
  })
})

app.listen(3000, () => {
  console.log('server is running on 3000')
})

通过浏览器分析get请求

这里使用应用层中间件为例,解释中间件的使用

  • 首先调用app.use()函数的中间件,将能够响应任何方法的请求。app.method()函数将处理对应HTTP方法的请求
  • 如果第一个参数没有传入路径参数,将默认解释为根路径(/
  • 支持传入多个中间件函数,但为了提高代码的可读性,尽量不要超过三个
  1. 首先nodex index.js运行上面的代码
  2. 在浏览器中输入localhost:3000/api/get-cookie
  3. 浏览器返回:{"errno":0,"data":{"userID":"abc123"}}

我们再查看控制台中的输出

$ node index.js
server is running on 3000
请求开始··· GET /api/get-cookie
处理 /api 路由
模拟登陆成功
get /api/get-cookie

让我们来借此分析一下,中间件的运行。
首先,app.use((req, res, next)...,这里是通过app.use注册的,并且没有指定响应路由参数,默认为/,将响应系统的所有路由和方式的请求,所以先输出了这里定义的回调函数(请求开始··· GET /api/get-cookie)。
其次,是第二个使用app.use()的定义的函数,定义了req.cookie

app.use((req, res, next) => {
  // 假设在处理 cookie
  req.cookie = {
    userID: 'abc123'
  }
  next()
})

再次,由于我们访问的地址为/api/get-cookie,这样会先访问到他的上级路径上定义的中间件函数,app.get('/api'),所以紧接着输出了处理 /api 路由
最后,进入到app.get('/api/get-cookie')定义的应用层中间件。首先依次执行loginCheckSuccess()中间件函数,返回模拟登陆成功next(),执行后面的中间件函数,res.json()为服务器返回了req.cookie中写入的值。

### 通过postman分析post请求

使用postman,在请求地址栏输入http://127.0.0.1:3000/api/get-post-deta,将返回{"errno":-1,"msg":"登陆失败"}

其执行原理和通过浏览器测试get请求类似,都是顺序执行了app.useapp.post的从根路径到目标路径上的中间件函数。不同的是,这里我们用loginCheckFailed()函数模拟了登录失败,这样由于登录失败,直接向postman中返回错误信息,将不再执行后面的中间件函数。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容