Express中间件的理解

2019-03-18  本文已影响0人  v刺猬v

中间件函数能够访问请求对象 (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请求

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

  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中返回错误信息,将不再执行后面的中间件函数。

上一篇 下一篇

猜你喜欢

热点阅读