基于JavaScript将表单序列化类型的数据转化成对象的处理(允许对象中包含对象)


Posted in Javascript onDecember 28, 2015

表单序列化类型的数据是指url传递的数据的格式,形如"key=value&key=value&key=value"这样的key/value的键值对。一般来说使用jQuery的$.fn.serialize函数能达到这样的效果。如何将这样的格式转化为对象?

我们知道使用jQuery的$.fn.serializeArray函数得到的是一个如下结构的对象

[
  {
    name: "startTime"
    value: "2015-12-02 00:00:00"
  },
  {
    name: "endTime"
    value: "2015-12-25 23:59:59"
  }
]

这是一个对象数组,但有时候我们希望得到的是如下结构的对象

{
  "startTime": "2015-12-02 00:00:00"
  "endTime": "2015-12-25 23:59:59"
}

所以这里需要一个转化函数。

处理步骤如下:

1.使用"&"分隔将每一个键值对分开然后循环处理每一个键值对

var properties = serializedParams.split("&");
  for (var i = 0; i < properties.length; i++) {
    //处理每一个键值对
    evalThem(properties[i]);
  };

2.从"="符号切分指定的键值对,并对每个键和值使用decodeURIComponent解析uri 组件编码(因为url传递的序列化数据一般都是经过uri组件编码的)

var strAry = new Array();
    strAry = str.split("=");
    //使用decodeURIComponent解析uri 组件编码
    for(var i = 0; i < strAry.length; i++){
      strAry[i] = decodeURIComponent(strAry[i]);
    }
    var attributeName = strAry[0];
    var attributeValue = strAry[1].trim();

3.如果值包含"="符号,需要额外处理(值合并)。       

if(strAry.length > 2){
      for(var i = 2;i<strAry.length;i++){
        attributeValue += "="+strAry[i].trim();
      }
    }

这里面有一个处理,就是值没有的时候就不会往最终对象里面添加。这个可以根据自己的情况选择删除这段代码与否

if(!attributeValue){
      return ;
    }

4.如果键是“obj.obj.obj”这种由"."符号链接的,需要将它作为对象包含对象来处理。处理的方法是将键通过"."分解,然后去查看临时对象obj中是否已经包含分解出来的对象,如果是则将数据附加到已有的对象上。源码如下  

var attriNames = attributeName.split("."),
      curObj = obj;
    for(var i = 0; i < (attriNames.length - 1); i++){
      curObj[attriNames[i]]?"":(curObj[attriNames[i]] = {});
      curObj = curObj[attriNames[i]];
    }
    curObj[attriNames[i]] = attributeValue.trim();

这里面我们看到网上有对赋值部分是这么处理的

eval("obj."+attributeName+"=\""+attributeValue.trim()+"\";");

这个很有问题,一个是不能正确处理4中对象包含对象的问题(尤其是有两个元素拥有同一个父对象的时候,比如"test.id=1&test.name='chua'"都拥有父对象test)。另外一个就是值attributeValue中包含单引号、双引号时无法正确处理。所以使用赋值"="最保险。

所以最终完整的源码如下

/*
serializedParams格式为"key1=value1&key2=value2". 
也支持'key.sonkey=value' 
 */
function paramString2obj (serializedParams) {  
  var obj={};
  function evalThem (str) {
    var strAry = new Array();
    strAry = str.split("=");
    //使用decodeURIComponent解析uri 组件编码
    for(var i = 0; i < strAry.length; i++){
      strAry[i] = decodeURIComponent(strAry[i]);
    }
    var attributeName = strAry[0];
    var attributeValue = strAry[1].trim();
    //如果值中包含"="符号,需要合并值
    if(strAry.length > 2){
      for(var i = 2;i<strAry.length;i++){
        attributeValue += "="+strAry[i].trim();
      }
    }
    if(!attributeValue){
      return ;
    }
    var attriNames = attributeName.split("."),
      curObj = obj;
    for(var i = 0; i < (attriNames.length - 1); i++){
      curObj[attriNames[i]]?"":(curObj[attriNames[i]] = {});
      curObj = curObj[attriNames[i]];
    }
    //使用赋值方式obj[attributeName] = attributeValue.trim();替换
    //eval("obj."+attributeName+"=\""+attributeValue.trim()+"\";");
    //解决值attributeValue中包含单引号、双引号时无法处理的问题
    curObj[attriNames[i]] = attributeValue.trim();
  };
  var properties = serializedParams.split("&");
  for (var i = 0; i < properties.length; i++) {
    //处理每一个键值对
    evalThem(properties[i]);
  };
  return obj;
}

以上内容是基于JavaScript将表单序列化类型的数据转化成对象的处理(允许对象中包含对象),希望本文分享能够给大家带来帮助。

Javascript 相关文章推荐
js传值 判断
Oct 26 Javascript
一些不错的js函数ajax
Aug 20 Javascript
JQuery最佳实践之精妙的自定义事件
Aug 11 Javascript
javascript如何创建表格(javascript绘制表格的二种方法)
Dec 10 Javascript
基于Bootstrap使用jQuery实现输入框组input-group的添加与删除
May 03 Javascript
JQuery的常用选择器、过滤器、方法全面介绍
May 25 Javascript
jQuery中绑定事件bind() on() live() one()的异同
Feb 23 Javascript
Angular.Js中ng-include指令的使用与实现
May 07 Javascript
vue中element组件样式修改无效的解决方法
Feb 03 Javascript
vue实现购物车的监听
Apr 20 Javascript
Javascript中Math.max和Math.max.apply的区别和用法详解
Aug 24 Javascript
HTML+VUE分页实现炫酷物联网大屏功能
May 27 Vue.js
浅析JS运动
Dec 28 #Javascript
基于JavaScript实现网页倒计时自动跳转代码
Dec 28 #Javascript
js时间戳转为日期格式的方法
Dec 28 #Javascript
jquery实现全屏滚动
Dec 28 #Javascript
AngularJS使用angular-formly进行表单验证
Dec 27 #Javascript
延时加载JavaScript代码提高速度
Dec 27 #Javascript
AngularJS使用ngMessages进行表单验证
Dec 27 #Javascript
You might like
PHP 只允许指定IP访问(允许*号通配符过滤IP)
2014/07/08 PHP
php生成图片验证码-附五种验证码
2015/08/19 PHP
php验证码实现代码(3种)
2015/09/07 PHP
PHP封装的字符串加密解密函数
2015/12/18 PHP
PHP文件上传类实例详解
2016/04/08 PHP
Javascript YUI 读码日记之 YAHOO.util.Dom - Part.3
2008/03/22 Javascript
js 模拟实现类似c#下的hashtable的简单功能代码
2010/01/24 Javascript
使用JavaScript switch case 另类写法
2010/03/14 Javascript
js function定义函数使用心得
2010/04/15 Javascript
jQuery 动画弹出窗体支持多种展现方式
2010/04/29 Javascript
使用indexOf等在JavaScript的数组中进行元素查找和替换
2013/09/18 Javascript
jquery合并表格中相同文本的相邻单元格
2015/07/17 Javascript
详解js的事件处理函数和动态创建html标记方法
2016/12/16 Javascript
JS实现商品筛选功能
2020/08/19 Javascript
JavaScript实现时间表动态效果
2017/07/15 Javascript
hammer.js实现图片手势放大效果
2017/08/29 Javascript
js 原生判断内容区域是否滚动到底部的实例代码
2017/11/15 Javascript
JS实现的数组去除重复数据算法小结
2017/11/17 Javascript
Vue.js搭建移动端购物车界面
2020/06/28 Javascript
微信小程序学习笔记之本地数据缓存功能详解
2019/03/29 Javascript
JS实现提示效果弹出及延迟隐藏的功能
2019/08/26 Javascript
在vue中使用Echarts利用watch做动态数据渲染操作
2020/07/20 Javascript
vue实现几秒后跳转新页面代码
2020/09/09 Javascript
[51:32]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
在PyCharm环境中使用Jupyter Notebook的两种方法总结
2018/05/24 Python
python三引号输出方法
2019/02/27 Python
python Django里CSRF 对应策略详解
2019/08/05 Python
Flask框架路由和视图用法实例分析
2019/11/07 Python
Python操作Sonqube API获取检测结果并打印过程解析
2019/11/27 Python
python实现代码审查自动回复消息
2021/02/01 Python
微信端html5页面调用分享接口示例
2018/03/14 HTML / CSS
100%有机精油,美容油:House of Pure Essence
2018/10/30 全球购物
Delphi笔试题
2016/11/14 面试题
专项法律服务方案
2014/06/11 职场文书
争先创优公开承诺书
2014/08/30 职场文书
sql查询结果列拼接成逗号分隔的字符串方法
2021/05/25 SQL Server