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请求,我们的代码大概是这样的。

<form action="/upload" method="post">   <label for="username">用户名:</label>   <input type="text" name="username" id="username" />  <label for="password">密码:</label>    <input type="password" name="password" id="password" />  <input type="submit" />    </form>

默认的表单提交,请求头中的 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发送的是文件数据

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

<form action="/upload" method="post" enctype="multipart/form-data"> <input type="file" name="avatar" id="avatar">    <input type="submit" />    </form>

默认的上传文件提交,请求头中的 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请求的方式,你都学会了吗?

Node中POST请求的正确处理方式相关推荐

  1. 运放中不使用引脚正确处理方式

    一块集成运算放大器通常包括多个分离的运放单元,一般我们不能全部用到,那么这些不使用的运放单元怎么处理?图1示意了一种元件最少的正确处理方式,图2是一些常见的错误方式,这些方式因为浮空输入或者地平面浮动 ...

  2. TensorFlow中RNN实现的正确打开方式

    上周写的文章<完全图解RNN.RNN变体.Seq2Seq.Attention机制>介绍了一下RNN的几种结构,今天就来聊一聊如何在TensorFlow中实现这些结构,这篇文章的主要内容为: ...

  3. TensorFlow中RNN实现的正确打开方式(转)

    上周写的文章<完全图解RNN.RNN变体.Seq2Seq.Attention机制>介绍了一下RNN的几种结构,今天就来聊一聊如何在TensorFlow中实现这些结构,这篇文章的主要内容为: ...

  4. mac怎么查node版本_node版本管理的正确打开方式(mac)

    前言 node官网首页 正如node官网所言,Node.js是一个Javascript运行环境(runtime environment),发布于2009年5月,由Ryan Dahl开发,实质是对Chr ...

  5. Trias系统中,staking的正确打开方式

    一.时间跳跃的分歧 staking毫无疑问名列今年最火爆的概念.眼下,越来越多的人争相恐后参与其中. 作为PoS机制下的挖矿手段,相比起比特币等PoW机制,staking不用耗费大量的算力资源,持币人 ...

  6. ajax 服务器压力,web中ajax请求后台的节流方式,减轻服务器压力

    场景 web前端中有一些需要与后台一起完成的用户体验,比如输入提示,下拉搜索等,监听键盘事件或者websocket流等不断的通过ajax向后台发送请求,获取详情的数据,而页面中的oninput,mou ...

  7. 在OKR中,CFR以正确的方式衡量绩效

    什么是OKR CFR?它们如何工作,以及如何向您介绍您的OKR? 在OKR中,CFR是连续绩效管理的缩写.OKR CFR使用OKR系统中的工具帮助您评估正在进行的进度.OKR CFR允许您定期检查目标 ...

  8. node中http的请求数据访问在浏览器中的基本使用方法和例子/静态资源库/url的基本使用/mime.json的内容和使用方式

    7.0 http 在node中的使用 7.1 http的基本演示:req:客户端请求的数据,res服务端响应的数据 let http = require("http"); // 创 ...

  9. Node中同步与异步的方式读取文件

    场景 Node.js最大的特点就是异步式I/O(或者非阻塞I/O)与事件紧密结合的编程模式.这种模式与传统的同步式I/O线性的编程思路有很大的不同,因为控制流很大程度上要靠事件和回调函数来组织,一个逻 ...

最新文章

  1. JAVA多线程两个实用的辅助类(CountDownLatch和AtomicBoolean)
  2. DL之YoloV3:Yolo V3算法的简介(论文介绍)、各种DL框架代码复现、架构详解、案例应用等配图集合之详细攻略
  3. ubuntu16.04设置ssh免密码登录
  4. Qt下Sqlite数据库操作
  5. SpringBoot项目遇到的一些问题
  6. 过期时间_2020年最新航空里程过期时间及避免过期方法总结
  7. java环境怎样搭建_如何学习JAVA?怎么搭建JAVA环境?怎么安装JDK?
  8. 如何在Java中检查对象是否为空?
  9. Bootstrap 导航条的组件
  10. 9型转x型 cobol_9家企业入列省首批试点 建设培育产教融合型企业
  11. 简单理解机器学习中的L1距离,L2距离,L-Inf距离
  12. OpenSolaris系统管理
  13. ORACLE常用工具介绍
  14. 递归求平均数|理解|讲解| c语言
  15. OTA再升级, 汽车云诊断风口将至,艾拉比早已“量产上车”
  16. 大厂的人自带光环,但光环是从哪儿来的呢?
  17. བྱ་དེ་ཁྲུང་ཁྲུང་དཀར་པོ།།--洁白的仙鹤/仓央嘉措情歌--IPA--藏语...
  18. ecshop 模板支持php,ecshop模板文件不支持php语句解决办法
  19. Openvpn搭建并使用用户名密码登录
  20. 电阻、电容及电感的高频等效电路及特性曲线

热门文章

  1. NBA 投篮数据可视化,4行代码就能实现!
  2. 金山云上市首日暴涨 40%,雷军:「All in」才有机会胜出
  3. 华为回应美新规:不涉及产品买卖;微软 GitHub 帐户疑被黑;GCC 10.1 发布 | 极客头条...
  4. 程序员有哪些丢不掉的编程“陋习”?
  5. 新手入坑自动驾驶,我是这么学习的......
  6. @程序员:别人身边的小姐姐是这样来的,你能学学吗
  7. 苹果首席设计官将离职;华为将从世界范围招揽天才少年;新版 Edge 更新 | 极客头条...
  8. Python 分析谁才是「权利的游戏」真正的主角?
  9. Google 程序员消灭 Bug 的 5 大法宝!
  10. Python 分析 35 年的考研英语真题词汇,解读孤独的考研大军!