浅谈Express.js解析Post数据类型的正确姿势


Posted in Javascript onMay 30, 2019

一、概念介绍

1、POST请求:HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 这几种。其中 POST 一般用来向服务端提交数据。

2、 Content-Type是指 http/https 发送信息至服务器时的内容编码类型, Content-Type 用于表明发送数据流的类型,服务器根据编码类型使用特定的解析方式,获取数据流中的数据。四种常见的 POST 请求的 Content-Type 数据类型:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • application/json
  • text/xml

3、 Express.jsExpress 是一个保持最小规模的灵活的 Node.js Web 应用程序开发框架,为 Web 和移动应用程序提供一组强大的功能。

本文我们主要介绍 Post 请求的 4 种 Content-Type 数据类型,以及如何使用 Express 来对每种 Content-Type 类型进行解析。已经将完整的代码实例上传到 github,github 地址为: https://github.com/fengshi123/request_example,欢迎 star 。

二、四种POST请求的Content-Type数据类型解析

1、application/x-www-form-unlencoded

最常见的 POST 提交数据的方式,浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会默认以 application/x-www-form-urlencoded 方式提交数据。

1.1、前端请求代码

var reqParam = "name=jack";
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(reqParam);

1.2、服务端解析代码

app.post('/urlencoded', bodyParser.urlencoded({extend:true}), function (req, res) {  
 var result = {
   name: req.body.name,    
   sex: '男',    
   age: 15  
 };  
 res.send(result);
});

1.3、浏览器请求 / 响应截图

请求:

浅谈Express.js解析Post数据类型的正确姿势

响应:

浅谈Express.js解析Post数据类型的正确姿势

2、multipart/form-data

使用表单上传文件时,必须指定表单的 enctype 属性值为 multipart/form-data . 请求体被分割成多部分,每部分使用 --boundary 分割开始,紧接着内容描述信息,最后是字段具体内容(文本或二进制);如果传输的是文件,还要包含文件名和文件类型信息;

2.1、前端请求代码

var reqParam = new FormData(document.form2);
xhr.send(reqParam);

2.2、服务端解析代码

express 提供了两种插件 formidablemultiparty 来处理数据类型为 multipart/form-data 的情况,以下我们分别用两个插件进行处理;

2.2.1、formidable 插件

(1)安装插件

npm install formidable --save

(2)服务端解析处理

app.post('/formData1', function (req, res) {  
  var form = new formidable.IncomingForm();  
  form.uploadDir = "upload/";  
  form.parse(req, function (err, fields, files) {    
   var obj = {};    
   Object.keys(fields).forEach(function (name) { 
     obj[name] = fields[name];    
   });    
   Object.keys(files).forEach(function (name) {      
     if (files[name] && files[name].name) {        
       obj[name] = files[name];        
       fs.renameSync(files[name].path, form.uploadDir + files[name].name);     
    }    
   });   
   res.send(obj);  
  });
});

2.2.2、multiparty 插件

(1)安装插件

npm install multiparty--save

(2)服务端解析处理

app.post('/formData2', function (req, res) {  
 // 解析一个文件上传  
var form = new multiparty.Form();  
//设置编辑  
form.encoding = 'utf-8';  
//设置文件存储路径  
form.uploadDir = "upload/";  
 //设置单文件大小限制  
form.maxFilesSize = 2000 * 1024 * 1024;  
form.parse(req, function (err, fields, files) {    
   var obj = {};    
   Object.keys(fields).forEach(function (name) {      
     obj[name] = fields[name];    
   });    
   Object.keys(files).forEach(function (name) {      
     if (files[name] && files[name][0] && files[name][0].originalFilename) {        
       obj[name] = files[name];        
       fs.renameSync(files[name][0].path, form.uploadDir + files[name][0].originalFilename); 
     }    
   });    
   res.send(obj);  
  });
});

2.3、浏览器请求 / 响应截图

请求:

浅谈Express.js解析Post数据类型的正确姿势

响应:

浅谈Express.js解析Post数据类型的正确姿势

3、application/json

application/json 这个 Content-Type 作为响应头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify ,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

3.1、前端请求代码

var reqParam = {  
   name: 'jack'
};
xhr.setRequestHeader('Content-type', 'application/json');
xhr.send(JSON.stringify(reqParam));

3.2、服务端解析代码

app.post('/applicationJson', bodyParser.json(), function (req, res) {  
var result = {    
  name: req.body.name,    
  sex: '男',    
  age: 15  
 };  
  res.send(result);
});

3.3、浏览器请求 / 响应截图

请求:

浅谈Express.js解析Post数据类型的正确姿势

响应:

浅谈Express.js解析Post数据类型的正确姿势

4、text/xml

它是一种使用 HTTP 作为传输协议, XML 作为编码方式的远程调用规范,它的使用也很广泛,能很好的支持已有的 XML-RPC 服务。不过, XML 结构还是过于臃肿,一般场景用 JSON 会更灵活方便。

4.1、前端请求代码

var text = '<?xml version="1.0"?><methodCall><methodName>examples.getStateName</methodName>' +  '<params><param><value><i4>41</i4></value></param></params></methodCall>';
xhr.setRequestHeader('Content-type', 'text/xml');
xhr.send(text);

4.2、服务端解析代码

app.post('/textXml', bodyParser.urlencoded({extend:true}), function (req, res) {  
  var result = ''; 
  req.on('data', function (chunk) {    
  result += chunk;  
  });  
  req.on('end', function () {    
  res.send(result);  
  });
});

4.3、浏览器请求 / 响应截图

请求:

浅谈Express.js解析Post数据类型的正确姿势

响应:

浅谈Express.js解析Post数据类型的正确姿势

三、踩坑汇总

1、对于跨域请求,当 contentType 改为 application/json ,将触发浏览器发送一个预检 OPTIONS 请求到服务器,再发送正常的 post 请求;

2、使用 new FormData() ,然后设置 Content-typeapplication/x-www-form-urlencoded 或者 multipart/form-data 会导致后端无法正常解析,解决方法:就是不进行头部设置, Content-type 会默认 为 multipart/form-data ,服务端正常解析;

3、 contentType 设置为 application/x-www-form-urlencoded 时,传给后端的请求参数为 JSON 字符串, chrome 调试框查看发送的请求参数多了冒号,如下所示:

浅谈Express.js解析Post数据类型的正确姿势

这是因为 application/x-www-form-urlencoded 它将被解析成键值对展示,但是字符串进去是没有改变的,但是展示的时候能看见。解决方法:如果为 JSON 字符串,则设置数据类型为 application/json

四、总结

本文我们主要介绍 Post 请求的 4 种 Content-Type 数据类型,以及如何使用 Express 来对每种 Content-Type 类型进行解析。已经将完整的代码实例上传到 githubgithub 地址为:https://github.com/fengshi123/request_example,欢迎 star demo 截图如下所示:

浅谈Express.js解析Post数据类型的正确姿势

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery分页插件jpaginate在IE中不兼容问题
Apr 22 Javascript
jQueryMobile之Helloworld与页面切换的方法
Feb 04 Javascript
教你如何使用firebug调试功能了解javascript闭包和this
Mar 04 Javascript
一些实用性较高的js方法
Apr 19 Javascript
Layui数据表格之获取表格中所有的数据方法
Aug 20 Javascript
示例vue 的keep-alive缓存功能的实现
Dec 13 Javascript
JavaScript学习教程之cookie与webstorage
Jun 23 Javascript
vue 自定义右键样式的实例代码
Nov 06 Javascript
node爬取新型冠状病毒的疫情实时动态
Feb 06 Javascript
JsonServer安装及启动过程图解
Feb 28 Javascript
js实现翻牌小游戏
Jul 31 Javascript
JavaScript架构搭建前端监控如何采集异常数据
Jun 25 Javascript
vue组件三大核心概念图文详解
May 30 #Javascript
详解一次Vue低版本安卓白屏问题的解决过程
May 30 #Javascript
基于iview的router常用控制方式
May 30 #Javascript
深入了解js原型模式
May 30 #Javascript
js逆向解密之网络爬虫
May 30 #Javascript
Vue.js中的组件系统
May 30 #Javascript
Vue+Django项目部署详解
May 30 #Javascript
You might like
php 处理上百万条的数据库如何提高处理查询速度
2010/02/08 PHP
php语言流程控制中的主动与被动
2012/11/05 PHP
php封装的验证码工具类完整实例
2016/10/19 PHP
PHPstorm快捷键(分享)
2017/07/17 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
2020/02/23 PHP
获取JavaScript用户自定义类的类名称的代码
2007/03/08 Javascript
onkeypress字符按键兼容所有浏览器使用介绍
2013/04/24 Javascript
顶部缓冲下拉菜单导航特效的JS代码
2013/08/27 Javascript
jquery改变disabled的boolean状态的三种方法
2013/12/13 Javascript
jQuery中对未来的元素绑定事件用bind、live or on
2014/04/17 Javascript
js判断元素是否隐藏的方法
2014/06/09 Javascript
图片放大镜jquery.jqzoom.js使用实例附放大镜图标
2014/06/19 Javascript
JavaScript设计模式之建造者模式介绍
2014/12/28 Javascript
Javascript基础教程之数据类型 (布尔型 Boolean)
2015/01/18 Javascript
JS通过ajax动态读取xml文件内容的方法
2015/03/24 Javascript
jQuery焦点图轮播特效代码分享(3款)
2015/09/05 Javascript
深入剖析JavaScript:Object类型
2016/05/10 Javascript
一步步教你利用webpack如何搭一个vue脚手架(超详细讲解和注释)
2018/01/08 Javascript
VUEJS 2.0 子组件访问/调用父组件的实例
2018/02/10 Javascript
Vue.set()动态的新增与修改数据,触发视图更新的方法
2018/09/15 Javascript
vue实现局部刷新的实现示例
2019/04/16 Javascript
vue和小程序项目中使用iconfont的方法
2020/05/19 Javascript
处理JavaScript值为undefined的7个小技巧
2020/07/28 Javascript
[01:00]DOTA2 store: Collection of Artisan's Wonders
2015/08/12 DOTA
[36:29]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 LGD vs TNC
2018/04/02 DOTA
使用Python解析JSON数据的基本方法
2015/10/15 Python
Python3.x爬虫下载网页图片的实例讲解
2018/05/22 Python
python实现给微信指定好友定时发送消息
2019/04/29 Python
Mac安装python3的方法步骤
2019/08/09 Python
Pycharm debug调试时带参数过程解析
2020/02/03 Python
django xadmin action兼容自定义model权限教程
2020/03/30 Python
python实现PDF中表格转化为Excel的方法
2020/06/16 Python
CSS3实现粒子旋转伸缩加载动画
2016/04/22 HTML / CSS
VIVOBAREFOOT赤脚鞋:让您的脚做自然的事情
2017/06/01 全球购物
台湾最大银发乐活百货:乐龄网
2018/05/21 全球购物
工作违纪的检讨书范文
2019/07/09 职场文书