博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Node中POST请求的正确处理方式
阅读量:5965 次
发布时间:2019-06-19

本文共 4160 字,大约阅读时间需要 13 分钟。

Node的 http 模块只对HTTP报文的头部进行了解析,然后触发 request 事件。如果请求中还带有内容部分(如 POST 请求,它具有报头和内容),内容部分需要用户自行接收和解析。

通过报头的 Transfer-EncodingContent-Length 即可判断请求中是否带有内容

字段名称 含义
Transfer-Encoding 指定报文主体的传输编码方式
Content-Length 报文主体的大小

写个方法判断是否有报文主体

const hasBody = function(req) {  return  'transfer-encoding'  in  req.headers  ||  'content-length' in req.headers;};复制代码

接收数据

报文内容部分会通过 data 事件触发,我们只需以流的方式处理即可,不要在订阅 data 事件的时候使用 += 的形式拼装数据,这样会乱码的。

function handle(req, res) {  if (hasBody(req)) {    var buffers = [];    req.on('data', function (chunk) {      buffers.push(chunk);    });    req.on('end', function () {      const POST = Buffer.concat(buffers).toString();    });  }}复制代码

1. POST发送的是表单的数据

如果在页面中使用表单提交一个post请求,我们的代码大概是这样的。

复制代码

默认的表单提交,请求头中的 Content-Type 字段值为 application/x-www-form-urlencoded

Content-Type: application/x-www-form-urlencoded复制代码

写一个判断内容类型的方法

const mime = function (req) {  const str = req.headers['content-type'] || '';  return str.split(';')[0];};复制代码

它的报文体内容跟查询字符串相同

username=Tom&password=123456复制代码

解析表单数据使用querystring模块中的parse方法

const querystring = require('querystring')function handleForm (req, res) {  const isFrom = mime(req) === 'application/x-www-form-urlencoded'  if (hasBody(req) && isFrom) {    var buffers = [];    req.on('data', function (chunk) {      buffers.push(chunk);    });    req.on('end', function () {      let requestBody = Buffer.concat(buffers).toString();      requestBody = querystring.parse(requestBody)    });  }}复制代码

2. POST发送的是JSON的数据

如果在页面中使用axios发送post请求,我们的代码大概是这样的。

axios.post('/user', {  username: 'Tom',  password: '123456'})复制代码

默认的JSON提交,请求头中的 Content-Type 字段值为 application/json,在 Content-Type 中可能还附带编码信息 charset=utf-8

Content-Type: application/json; charset=utf-8复制代码

它的报文体内容跟JSON格式的字符串相同

{  "name": "Tom",  "password": "123456"}复制代码

解析JSON数据使用 JSON.parse 方法。

function handleJson (req, res) {  const isJson = mime(req) === 'application/json'  if (hasBody(req) && isJson) {    var buffers = [];    req.on('data', function (chunk) {      buffers.push(chunk);    });    req.on('end', function () {      let requestBody = Buffer.concat(buffers).toString();      try {        requestBody = JSON.parse(requestBody)      } catch (error) {        console.log(error)      }    });  }}复制代码

3. POST发送的是文件数据

如果在页面中使用表单提交文件请求,我们的代码大概是这样的。

复制代码

默认的上传文件提交,请求头中的 Content-Type 字段值为multipart/form-data,在 Content-Type 中可能还附带内容分隔符 boundary=----WebKitFormBoundary4Hsing01Izo2AHqv

Content-Type: multipart/form-data; boundary=----WebKitFormBoundary4Hsing01Izo2AHqv复制代码

先上传一个JS文件,看看报文主体里面的格式大概是这样的,包含文件信息和文件内容,有指定的分隔符包裹。

上传文件的时候是要区分文本文件和二进制文件,文本文件是要使用 utf8 编码(HTML,CSS,JavaScript),二进制文件是要使用 binary 编码(图片,视频,音频)

根据内容分隔符解析上传的图片,并且写入到文件中,下面代码暂时只处理图片格式的文件。

function handleFile(req, res) {  const isFile = mime(req) === 'multipart/form-data'  if (hasBody(req) && isFile) {    var buffers = [];    req.on('data', function (chunk) {      buffers.push(chunk);    });    req.on('end', function () {      // 处理文件名      let requestBody = Buffer.concat(buffers).toString('binary');      let file = querystring.parse(requestBody, '\r\n', ': ')      let fileInfo = file['Content-Disposition']      fileInfo = Buffer.from(fileInfo, 'binary').toString()      let { filename } = querystring.parse(fileInfo, '; ', '=')      filename = filename.slice(1, -1)      filename = `./static/${filename}`      // 处理内容      let boundary = req.headers['content-type'].split('; ')[1].replace('boundary=', '');      let contentType = file['Content-Type']      if (!contentType.includes('image')) return      let upperBoundary = requestBody.indexOf(contentType) + contentType.length;      let shorterData = requestBody.substring(upperBoundary)      let binaryDataAlmost = shorterData.trim()      let binaryData = binaryDataAlmost.substring(0, binaryDataAlmost.indexOf(`--${boundary}--`))      // 写入文件      fs.writeFile(filename, binaryData, 'binary', (err) => {        if (err) {          console.log('上传失败')        } else {          console.log('上传成功', filename)        }      })    });  }}复制代码

这就是所有处理POST请求的方式,你都学会了吗?

转载于:https://juejin.im/post/5d0a431e6fb9a07ea71314f8

你可能感兴趣的文章
2018年尾总结——稳中成长
查看>>
JFreeChart开发_用JFreeChart增强JSP报表的用户体验
查看>>
度量时间差
查看>>
通过jsp请求Servlet来操作HBASE
查看>>
Shell编程基础
查看>>
Shell之Sed常用用法
查看>>
3.1
查看>>
校验表单如何摆脱 if else ?
查看>>
<气场>读书笔记
查看>>
Centos下基于Hadoop安装Spark(分布式)
查看>>
3D地图的定时高亮和点击事件(基于echarts)
查看>>
mysql开启binlog
查看>>
设置Eclipse编码方式
查看>>
分布式系统唯一ID生成方案汇总【转】
查看>>
并查集hdu1232
查看>>
Mysql 监视工具
查看>>
从前后端分离到GraphQL,携程如何用Node实现?\n
查看>>
Linux Namespace系列(09):利用Namespace创建一个简单可用的容器
查看>>
博客搬家了
查看>>
Python中使用ElementTree解析xml
查看>>