为什么需要bodyParser这个中间件?

前言

​ 好多天没有写关于JS开发的文章了,主要是最近的事情太多了,今天也不知道写啥好,然后注意到我们在写http服务的时候,通常直接用一个中间件body-parser够拿到我们post请求中传递的参数。

前端代码

先来看一下我们的测试代码,

下面就是我们今天的页面代码,我这里直接给大家用html去写了,在这个页面我们引入了axios的一个cdn链接,然后加了一个点击按钮,点击按钮之后我们会向后端发送一个post请求,在请求头中我们添加了一个JSON数据传递到服务器端。

/* index.html */

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <style>
    body {
      width: 100vw;
      height: 100vh;
      background-color: #fff;
    }
  </style>
</head>
<body>
  <button onclick="handlePost()">发送数据</button>

  <script>
    function handlePost() {
      axios.post('/data', {
        name: 'TT',
        age: '25'
      }).then((data) => {
        console.log(data)
      }).catch((error) =>{
        console.error(error)
      })
    }
  </script>
</body>
</html>

后端代码

我们再来看一下后端代码;

服务端这边我就用express模块直接搭建一个简单的服务,然后这里添加一个post的请求路由,

这里可以看到并没有加入 body-parser 中间件,

先直接给大家打印一下请求对象中是否存在body属性,再打印一下body属性值(如果存在的话),最后不能忘了给请求一个响应。

/* app.js */

const express = require('express');
const path = require('path')
const app = express();
app.use(express.static(path.join(__dirname)));

app.post('/data', (req, res) => {
  console.log(Object.keys(req).includes('body'), req.body)
  res.send('success')
})

app.listen(3000, '127.0.0.1', () => {
  console.log(`Server running at http://127.0.0.1:3000`)
});

直接看一下打印结果

为什么需要bodyParser这个中间件?

从打印结果来看此时我们的请求对象中是没有body属性的,那我们如何能够拿到传递的数据呢?

我们都知道我们一般发起post类型的网络请求,请求数据会放在body里面,但是上面的打印中我们并没有从请求对象中拿到我们的body,因为这边的话,我们的body数据是通过数据流的形式传递到我们的服务器的,但是我们的传输数据是放在body中的,那我们这里就必须通过接收流来拿到我们的数据,大家再看一下我们通过接收数据流后的代码。

/* app.js */

const express = require('express');
const path = require('path')
const app = express();
app.use(express.static(path.join(__dirname)));

app.post('/data', (req, res) => {
  console.log(Object.keys(req).includes('body'), req.body)

  const chunkData = [];
  let size = 0;
  req.on('data', data => {
    console.log('data: ', data instanceof Buffer)
    chunkData.push(data);
    size += data.length;
  })

  req.on('end', () => {
    const data = Buffer.concat(chunkData, size)
    console.log('end: ', size, data.toString());
    res.send('success')
  })
})

app.listen(3000, '127.0.0.1', () => {
  console.log(`Server running at http://127.0.0.1:3000`)
});

我这里在服务端的post请求路由回调中,通过监听了请求对象的dataend事件,在data事件中接收通过流传递过来的body数据,然后在接收完数据之后在end事件中将数据流合并,然后通过字符串的形式打印出来,我们再来看一下打印结果。

为什么需要bodyParser这个中间件?

大家可以看到我们在data事件中拿到的数据类型的确是流数据,并且我们在接收完所有的数据流后,在end事件中通过字符串类型将数据打印了出来,这时候我们可以看到我们通过页面向服务传递的JSON数据被成功的打印出来。

说明我们可以通过流的形式去接收到前端post请求传递过来的数据,但是每次都这样处理肯定是很麻烦的,所以说我们一般直接通过body-parser中间件对我们的post请求的数据流进行处理。

那么到这里大家应该也能够知道我们的body-parser中间件做的工作是什么样的,当然,这里我只是给大家演示了一下基础的内容,但是在中间件中,实际还是有很多情况需要处理的,

最后我们安装一下body-parser这个中间件再看一下效果,

/* app.js */
const express = require('express');
const path = require('path')
const app = express();
const bodyParser = require('body-parser');
app.use(express.static(path.join(__dirname)));
app.use(bodyParser.json());

app.post('/data', (req, res) => {
  console.log(Object.keys(req).includes('body'), req.body)
  res.send('success')
})

app.listen(3000, '127.0.0.1', () => {
  console.log(`Server running at http://127.0.0.1:3000`)
});

为什么需要bodyParser这个中间件?

大家可以看到使用了body-parser中间件之后,我们的请求对象中就多了一个body属性,打印出来可以看到是我们前端传递的数据参数。

大家如果感兴趣的话也可以去看一下body-parser这个中间件的源码,这里就不给大家去贴源码了

总结

马上不是要2022了嘛,最近手里的工作也比较多,所以说文章更新可能会降低下频率,如果写的内容有错的,也欢迎大家积极留言,感谢各位大佬赏脸!

上一篇:如何在不支持ypchsh的远程计算机中更改Linux shell


下一篇:nodeStudy Day01