浅谈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 相关文章推荐
鼠标移动到图片名上,显示图片的简单实例
Jul 14 Javascript
jQuery+ajax实现鼠标单击修改内容的方法
Jun 27 Javascript
jquery.cookie.js实现用户登录保存密码功能的方法
Apr 15 Javascript
JS获取年月日时分秒的方法分析
Nov 28 Javascript
Vue.2.0.5过渡效果使用技巧
Mar 16 Javascript
angular+ionic返回上一页并刷新页面
Aug 08 Javascript
vue-resource拦截器设置头信息的实例
Oct 27 Javascript
vue通过点击事件读取音频文件的方法
May 30 Javascript
vue中设置height:100%无效的问题及解决方法
Jul 27 Javascript
浅谈React之状态(State)
Sep 19 Javascript
新年快乐! javascript实现超级炫酷的3D烟花特效
Jan 30 Javascript
使用Node.js在深度学习中做图片预处理的方法
Sep 18 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
Zend Framework框架之Zend_Mail实现发送Email邮件验证功能及解决标题乱码的方法
2016/03/21 PHP
php 微信开发获取用户信息如何实现
2016/12/13 PHP
javascript入门·对象属性方法大总结
2007/10/01 Javascript
基于jquery库的tab新形式使用
2012/11/16 Javascript
批量实现面向对象的实例代码
2013/07/01 Javascript
jQuery中$.fn的用法示例介绍
2013/11/05 Javascript
Javascript之this关键字深入解析
2013/11/12 Javascript
详解JavaScript数组的操作大全
2015/10/19 Javascript
举例说明JavaScript中的实例对象与原型对象
2016/03/11 Javascript
JavaScript的Ext JS框架中的GridPanel组件使用指南
2016/05/21 Javascript
JS 动态判断PC和手机浏览器实现代码
2016/09/21 Javascript
关于js函数解释(包括内嵌,对象等)
2016/11/20 Javascript
React为 Vue 引入容器组件和展示组件的教程详解
2018/05/03 Javascript
nodejs取得当前执行路径的方法
2018/05/13 NodeJs
vue 实现左右拖拽元素并且不超过他的父元素的宽度
2018/11/30 Javascript
vuex 多模块时 模块内部的mutation和action的调用方式
2020/07/24 Javascript
vue解决跨域问题(推荐)
2020/11/10 Javascript
Vue 列表页带参数进详情页的操作(router-link)
2020/11/13 Javascript
python读写文件操作示例程序
2013/12/02 Python
12步入门Python中的decorator装饰器使用方法
2016/06/20 Python
解决pandas 作图无法显示中文的问题
2018/05/24 Python
简单了解django索引的相关知识
2019/07/17 Python
python KNN算法实现鸢尾花数据集分类
2019/10/24 Python
python怎么判断模块安装完成
2020/06/19 Python
详解python UDP 编程
2020/08/24 Python
解决Python import .pyd 可能遇到路径的问题
2021/03/04 Python
html5 移动端视频video的android兼容(去除播放控件、全屏)
2020/03/26 HTML / CSS
比利时的在线灯具店:Lampen24.be
2019/07/01 全球购物
集体婚礼策划方案
2014/02/22 职场文书
卫生巾广告词
2014/03/18 职场文书
群众路线领导对照材料
2014/08/23 职场文书
健康状况证明书
2014/11/26 职场文书
个人典型事迹材料
2014/12/30 职场文书
2015年“公民道德宣传日”活动方案
2015/05/06 职场文书
无工作证明怎么写
2015/06/15 职场文书
MySQL sql模式设置引起的问题
2022/05/15 MySQL