基于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 相关文章推荐
javascript xml为数据源的下拉框控件
Jul 07 Javascript
jquery 简单的进度条实现代码
Mar 11 Javascript
js将当前时间格式转换成时间搓(自写)
Sep 26 Javascript
js实现通用的微信分享组件示例
Mar 10 Javascript
jQuery判断元素上是否绑定了指定事件的方法
Mar 17 Javascript
jQuery中closest和parents的区别分析
May 07 Javascript
基于jquery css3实现点击动画弹出表单源码特效
Aug 31 Javascript
第六章之辅组类与响应式工具
Apr 25 Javascript
jquery.qtip提示信息插件用法简单实例
Jun 17 Javascript
细说webpack源码之compile流程-rules参数处理技巧(1)
Dec 26 Javascript
JavaScript遍历数组的三种方法map、forEach与filter实例详解
Feb 27 Javascript
vue.js 子组件无法获取父组件store值的解决方式
Nov 08 Javascript
浅析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
第十二节--类的自动加载
2006/11/16 PHP
php生成随机数或者字符串的代码
2008/09/05 PHP
zf框架的db类select查询器join链表使用示例(zend框架)
2014/03/14 PHP
ThinkPHP模型详解
2015/07/27 PHP
ThinkPHP框架结合Ajax实现用户名校验功能示例
2019/07/03 PHP
PHP设计模式之外观模式(Facade)入门与应用详解
2019/12/13 PHP
JavaScript 事件记录使用说明
2009/10/20 Javascript
jquery动画2.元素坐标动画效果(创建一个图片走廊)
2012/08/24 Javascript
jquery ajax实现下拉框三级无刷新联动,且保存保持选中值状态
2013/10/29 Javascript
在页面上用action传递参数到后台出现乱码的解决方法
2013/12/31 Javascript
自己使用jquery写的一个无缝滚动的插件
2014/04/30 Javascript
一张Web前端的思维导图分享
2015/07/03 Javascript
JavaScript小技巧整理篇(非常全)
2016/01/26 Javascript
浅析javascript中的Event事件
2016/12/09 Javascript
微信小程序实现tab和swiper切换结合效果
2020/07/17 Javascript
Node错误处理笔记之挖坑系列教程
2018/06/05 Javascript
关于JavaScript中高阶函数的魅力详解
2018/09/07 Javascript
Vue CLI 3.x 自动部署项目至服务器的方法
2019/04/02 Javascript
vue实现微信分享链接添加动态参数的方法
2019/04/29 Javascript
javascript实现下拉菜单效果
2021/02/09 Javascript
详谈tensorflow gfile文件的用法
2020/02/05 Python
IntelliJ 中配置 Anaconda的过程图解
2020/06/01 Python
Python类的继承super相关原理解析
2020/10/22 Python
用Python自动清理系统垃圾的实现
2021/01/18 Python
HTML5如何实现元素拖拽
2016/03/11 HTML / CSS
巴西最大的家电和百货零售商:Casas Bahia
2016/11/22 全球购物
STAY JAPAN台湾:预订日本民宿
2018/07/22 全球购物
英国家用电器折扣网站:Electrical Discount UK
2018/09/17 全球购物
德国领先的大尺码和超大尺码男装在线零售商:Bigtex
2019/06/22 全球购物
C#面试问题
2016/07/29 面试题
酒店保洁主管岗位职责
2013/11/28 职场文书
企业党建工作汇报材料
2014/08/19 职场文书
汽车转让协议书范本
2014/12/07 职场文书
天鹅湖观后感
2015/06/09 职场文书
升学宴家长答谢词
2015/09/29 职场文书
nginx搭建NFS网络文件系统
2022/04/14 Servers