Node中POST请求的正确处理方式
Node的 http 模块只对HTTP报文的头部进行了解析,然后触发 request
事件。如果请求中还带有内容部分(如 POST 请求,它具有报头和内容),内容部分需要用户自行接收和解析。
通过报头的 Transfer-Encoding
或 Content-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示意了一种元件最少的正确处理方式,图2是一些常见的错误方式,这些方式因为浮空输入或者地平面浮动 ...
- TensorFlow中RNN实现的正确打开方式
上周写的文章<完全图解RNN.RNN变体.Seq2Seq.Attention机制>介绍了一下RNN的几种结构,今天就来聊一聊如何在TensorFlow中实现这些结构,这篇文章的主要内容为: ...
- TensorFlow中RNN实现的正确打开方式(转)
上周写的文章<完全图解RNN.RNN变体.Seq2Seq.Attention机制>介绍了一下RNN的几种结构,今天就来聊一聊如何在TensorFlow中实现这些结构,这篇文章的主要内容为: ...
- mac怎么查node版本_node版本管理的正确打开方式(mac)
前言 node官网首页 正如node官网所言,Node.js是一个Javascript运行环境(runtime environment),发布于2009年5月,由Ryan Dahl开发,实质是对Chr ...
- Trias系统中,staking的正确打开方式
一.时间跳跃的分歧 staking毫无疑问名列今年最火爆的概念.眼下,越来越多的人争相恐后参与其中. 作为PoS机制下的挖矿手段,相比起比特币等PoW机制,staking不用耗费大量的算力资源,持币人 ...
- ajax 服务器压力,web中ajax请求后台的节流方式,减轻服务器压力
场景 web前端中有一些需要与后台一起完成的用户体验,比如输入提示,下拉搜索等,监听键盘事件或者websocket流等不断的通过ajax向后台发送请求,获取详情的数据,而页面中的oninput,mou ...
- 在OKR中,CFR以正确的方式衡量绩效
什么是OKR CFR?它们如何工作,以及如何向您介绍您的OKR? 在OKR中,CFR是连续绩效管理的缩写.OKR CFR使用OKR系统中的工具帮助您评估正在进行的进度.OKR CFR允许您定期检查目标 ...
- node中http的请求数据访问在浏览器中的基本使用方法和例子/静态资源库/url的基本使用/mime.json的内容和使用方式
7.0 http 在node中的使用 7.1 http的基本演示:req:客户端请求的数据,res服务端响应的数据 let http = require("http"); // 创 ...
- Node中同步与异步的方式读取文件
场景 Node.js最大的特点就是异步式I/O(或者非阻塞I/O)与事件紧密结合的编程模式.这种模式与传统的同步式I/O线性的编程思路有很大的不同,因为控制流很大程度上要靠事件和回调函数来组织,一个逻 ...
最新文章
- JAVA多线程两个实用的辅助类(CountDownLatch和AtomicBoolean)
- DL之YoloV3:Yolo V3算法的简介(论文介绍)、各种DL框架代码复现、架构详解、案例应用等配图集合之详细攻略
- ubuntu16.04设置ssh免密码登录
- Qt下Sqlite数据库操作
- SpringBoot项目遇到的一些问题
- 过期时间_2020年最新航空里程过期时间及避免过期方法总结
- java环境怎样搭建_如何学习JAVA?怎么搭建JAVA环境?怎么安装JDK?
- 如何在Java中检查对象是否为空?
- Bootstrap 导航条的组件
- 9型转x型 cobol_9家企业入列省首批试点 建设培育产教融合型企业
- 简单理解机器学习中的L1距离,L2距离,L-Inf距离
- OpenSolaris系统管理
- ORACLE常用工具介绍
- 递归求平均数|理解|讲解| c语言
- OTA再升级, 汽车云诊断风口将至,艾拉比早已“量产上车”
- 大厂的人自带光环,但光环是从哪儿来的呢?
- བྱ་དེ་ཁྲུང་ཁྲུང་དཀར་པོ།།--洁白的仙鹤/仓央嘉措情歌--IPA--藏语...
- ecshop 模板支持php,ecshop模板文件不支持php语句解决办法
- Openvpn搭建并使用用户名密码登录
- 电阻、电容及电感的高频等效电路及特性曲线
热门文章
- NBA 投篮数据可视化,4行代码就能实现!
- 金山云上市首日暴涨 40%,雷军:「All in」才有机会胜出
- 华为回应美新规:不涉及产品买卖;微软 GitHub 帐户疑被黑;GCC 10.1 发布 | 极客头条...
- 程序员有哪些丢不掉的编程“陋习”?
- 新手入坑自动驾驶,我是这么学习的......
- @程序员:别人身边的小姐姐是这样来的,你能学学吗
- 苹果首席设计官将离职;华为将从世界范围招揽天才少年;新版 Edge 更新 | 极客头条...
- Python 分析谁才是「权利的游戏」真正的主角?
- Google 程序员消灭 Bug 的 5 大法宝!
- Python 分析 35 年的考研英语真题词汇,解读孤独的考研大军!