美文网首页nodejs
POST三种常见的数据格式及NodeJS后台解析

POST三种常见的数据格式及NodeJS后台解析

作者: TPKCJJ | 来源:发表于2019-10-06 15:53 被阅读0次

    前言:我们知道,服务端通常是根据请求头(headers)里面的 Content-Type 字段来判断请求中的消息主体是用何种方式进行编码的,然后再对主体进行解析。所以我们需要先了解一下POST的数据编码格式。

    POST数据编码格式

    POST的数据编码格式由Content-Type决定,而Content-Type有多种值,每个值都代表不同的数据格式

    1、常见的媒体格式类型:

    • text/html : HTML格式
    • text/plain :纯文本格式
    • text/xml : XML格式
    • image/gif :gif图片格式
    • image/jpeg :jpg图片格式
    • image/png:png图片格式

    2、以applicaton开头的媒体类型:

    • application/json : JSON数据格式
    • application/xhtml+xml :XHTML格式
    • application/xml : XML数据格式
    • application/atom+xml :Atom XML聚合格式
    • application/pdf :pdf格式
    • application/javascript :js格式
    • application/msword : Word文档格式
    • application/octet-stream : 二进制流数据(如常见的文件下载)
    • application/x-www-form-urlencoded :form表单默认的数据格式类型,form表单数据被编码为key/value格式发送到服务器。

    另外一种常见的媒体格式是上传文件之时使用的:
    multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式。

    其中POST提交可能用到的Content-Type类型如下:

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

    在此我们会讨论其中常见的三种数据格式及其后台解析操作,为了方便测试,我们采用ApiPost(也可以使用PostMan)接口调试软件发起POST请求,后台则用NodeJS+Express搭配服务器。

    后台解析请求主体的数据可能需要安装的模块,body-parser,multiparty;
    其中,body-parser可用于express对请求进行分析,根据req.body字段便可以获得请求的主体。由于body-parser与Express分离了,所以需要自己重新安装该模块
    安装命令:npm install body-parser
    multiparty可用于接收提交的文件和解析form-data编码的数据
    安装命令:npm install multiparty

    // 引入模块
    var express = require('express');
    var path = require('path');
    var ejs = require('ejs');
    var app = express();
    //var bodyParser=require('body-parser');
    
    // app.use(bodyParser.json());
    // app.use(bodyParser.urlencoded({ extended: false }));
    
    // 数据post接口路由
    app.post('/action/:module', function (req, res) {
        var c_path = req.params.module;
        var Action = require('./action/' + c_path);
        Action.execute(req, res);
    });
    
    // 设置views路径和模板
    app.set('views', __dirname);
    app.set('view engine', 'html');
    app.engine('html', ejs.__express);
     
    app.use('/', express.static(__dirname));
    // 启动一个服务,监听从8080端口进入的所有连接请求
    var server = app.listen(8888, function(){
        var host = server.address().address;
        var port = server.address().port;
        console.log('Listening at http://%s:%s', host, port);
    });
    

    PS:这里我的测试接口为http://localhost:8888/action/postTry,该接口会将POST请求里面的请求主体返回,这样我们可以看到POST的 数据在不同编码格式中是如何进行编码的

    一、application/x-www-form-urlencoded
    主要用于如下:
    1.1、最常见的POST提交数据方式。
    1.2、原生form默认的提交方式(可以使用enctype指定提交数据类型)。
    1.3、jquery,zepto等默认post请求提交的方式

    application/x-www-form-urlencoded 是最常用的一种请求编码方式,支持GET/POST等方法,所有数据变成键值对的形式 key1=value1&key2=value2
    的形式,并且特殊字符需要转义成utf-8编号,如空格会变成 %20;

    开始测试:

    发送请求

    用ApiPost发送请求,选择编码格式为application/x-www-form-urlencoded,我们输入字段name和value作为传送的参数,分别取值为111111和22222,在ApiPost可以查看返回的数据


    application/x-www-form-urlencoded.png
    解析数据

    由图片结果,我们可以看到我们发送的请求主体里面的数据为以下结果

    name=111111&value=22222
    

    这与我们上述所述一致,现在我们需要在NodeJS里面进行解析,得到数据。以下为服务端解析代码

    //导入querystring模块(解析post请求数据)
    var querystring = require('querystring');
    exports.execute = function (req, res) {
        //console.log(req.body)   
        /*如果使用了body-parser,则可以使用使用req.body获取到请求主体,
        但是下方的req.on事件就会失去作用,因为此时数据以及接收完毕,所以没有办法触发处理事件*/
        //面对post提交,nodejs用监听的写法处理
        //data是一个事件,表示一个小包传输完毕后做的事情
        var result = "";
        req.on("data", function (chunk) {
            //console.log("小包传输完毕");
            result += chunk;
        });
        //end也是一个事件,表示所有的包传输完毕
        req.on("end", function () {
            //所有的包传输完毕
            result = decodeURI(result); // 前端提交中文数据时会进行url编码,所以先进行译码
            var resultObject = querystring.parse(result);//对数据进行解析
            //var result = JSON.parse(result);
            //console.log(resultObject);
            console.log(resultObject)//打印解析结果
            message['status'] = 200;
            message['msg'] = '提交成功';
            res.send(result)
        });
    };
    

    由于x-www-form-urlencoded是类似于url编码的一种编码方式,所以我们可以利用NodeJS内置的querystring模块进行解析,打印的解析结果如下:

    [Object: null prototype] { name: '111111', value: '22222' }
    

    这时候我们已经成功将请求主体由字符串解析为对象,可以通过访问对象属性的方式进行数据的访问。

    二、multipart/form-data
    使用表单上传文件时,必须指定表单的 enctype属性值为 multipart/form-data. 请求体被分割成多部分,每部分使用 --boundary分割;

    开始测试:

    发送请求

    用ApiPost发送请求,选择编码格式为multipart/form-data,我们输入字段name和value作为传送的参数,分别取值为111111和22222,在ApiPost可以查看返回的数据


    multipart/form-data.png
    解析数据

    由图片结果,我们可以看到我们发送的请求主体里面的数据为以下结果

    ------WebKitFormBoundaryeDD6NSO9tLOAABh5
    Content-Disposition: form-data; name="name"
    
    111111
    ------WebKitFormBoundaryeDD6NSO9tLOAABh5
    Content-Disposition: form-data; name="value"
    
    22222
    ------WebKitFormBoundaryeDD6NSO9tLOAABh5--
    

    由于NodeJS无法使用querystring直接将以上请求主体直接解析为对象,另外,上述提到的body-parser也不支持解析form-data编码的数据,此时的req.body={},这时候我们可以使用multiparty模块来进行数据的解析,具体可查看以下代码

    var multiparty = require('multiparty');
        //生成multiparty对象,并配置文件上传目标路径
        var form = new multiparty.Form({ uploadDir: 'images/images' });
        form.parse(req, function(err, fields, files) {
            var message = {};
            if (err) {
                message["Code"] = 1;
                message["Msg"] = err;
            } else {
                message['name'] = fields.name[0]; //可根据fields获取其他数据,name以及values
                message['value'] = fields.value[0];
            }
            res.send(message);
        });
    

    打印结果如下

    { name: '111111', value: '22222' }
    

    三、application/json
    实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。而且现在服务端基本都可以处理JSON数据,所以不会出现什么大问题。

    开始测试:

    发送请求

    用ApiPost发送请求,选择编码格式为application/json,我们输入字段name和value作为传送的参数,分别取值为111111和222222,在ApiPost可以查看返回的数据


    application/json.png
    解析数据

    由图片结果,我们可以看到我们发送的请求主体里面的数据为以下结果

    {
        "name": "111111",
        "value": "222222"
    }
    

    此时的数据解析我们可以用JSON.parse对字符串进行解析获得对象

        // res.send(req.body)
        //面对post提交,nodejs用监听的写法处理
        //data是一个事件,表示一个小包传输完毕后做的事情
        var result = "";
        req.on("data", function (chunk) {
            //console.log("小包传输完毕");
            result += chunk;
        });
        //end也是一个事件,表示所有的包传输完毕
        req.on("end", function () {
            //所有的包传输完毕
            result = decodeURI(result); // 前端中文数据提交时会进行url编码,所以先进行译码
            var resultObject = JSON.parse(result);
            console.log(resultObject)
            res.send(result)
        });
    

    打印结果如下

    { name: '111111', value: '222222' }
    

    另外,我们常用的axios HTTP工具库发起的axios post方法默认使用application/json格式编码数据,这个也可以说明在post请求中,使用这种编码格式应该是更加方便的。

    个人觉得,在不需要进行文件上传的操作的时候,尽量还是选择application/json,因为在后台对数据的解析会变得比较简单,服务器基本都已经可以实现json数据的解析和封装了。

    相关文章

      网友评论

        本文标题:POST三种常见的数据格式及NodeJS后台解析

        本文链接:https://www.haomeiwen.com/subject/pddupctx.html