基于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 相关文章推荐
许愿墙中用到的函数
Oct 07 Javascript
WEB 浏览器兼容 推荐收藏
May 14 Javascript
CSS和Javascript简单复习资料
Jun 29 Javascript
在jQuery 1.5中使用deferred对象的代码(翻译)
Mar 10 Javascript
js渐变显示渐变消失示例代码
Aug 01 Javascript
javascript事件函数中获得事件源的两种不错方法
Mar 17 Javascript
window.print打印指定div指定网页指定区域的方法
Aug 04 Javascript
PHP实现的各种中文编码转换类分享
Jan 23 Javascript
js实现透明度渐变效果的方法
Apr 10 Javascript
Javascript获取数组中的最大值和最小值的方法汇总
Jan 01 Javascript
深入理解Node.js的HTTP模块
Oct 12 Javascript
js 中rewrap-ajax.js插件实例代码
Oct 20 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
基于PHP array数组的教程详解
2013/06/05 PHP
PHP设计模式之委托模式定义与用法简单示例
2018/08/13 PHP
利用javascript查看html源文件
2006/11/08 Javascript
js获取html页面节点方法(递归方式)
2013/12/13 Javascript
jQuery实现简单网页遮罩层/弹出层效果兼容IE6、IE7
2014/06/16 Javascript
jquery让返回的内容显示在特定div里(代码少而精悍)
2014/06/23 Javascript
JavaScript实现点击按钮直接打印
2016/01/06 Javascript
AngularJS入门(用ng-repeat指令实现循环输出
2016/05/05 Javascript
Angular ng-repeat 对象和数组遍历实例
2016/09/14 Javascript
详解vue-validator(vue验证器)
2017/01/16 Javascript
JS使用面向对象技术实现的tab选项卡效果示例
2017/02/28 Javascript
十大热门的JavaScript框架和库
2017/03/21 Javascript
JavaScript的六种继承方式(推荐)
2017/06/26 Javascript
Angular 4.X开发实践中的踩坑小结
2017/07/04 Javascript
原生JS+Canvas实现五子棋游戏
2020/05/28 Javascript
JS设计模式之访问者模式定义与用法分析
2018/02/05 Javascript
vue实现a标签点击高亮方法
2018/03/17 Javascript
详解vue使用插槽分发内容slot的用法
2019/03/28 Javascript
在vue项目中使用sass语法问题
2019/07/18 Javascript
ElementUI radio组件选中小改造
2019/08/12 Javascript
微信小程序登陆注册功能的实现代码
2019/12/10 Javascript
JS校验与最终登陆界面功能完整示例
2020/01/13 Javascript
python中requests模块的使用方法
2015/04/08 Python
Python中使用urllib2模块编写爬虫的简单上手示例
2016/01/20 Python
python 写入csv乱码问题解决方法
2016/10/23 Python
TensorFlow梯度求解tf.gradients实例
2020/02/04 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
2020/02/22 Python
Python处理mysql特殊字符的问题
2020/03/02 Python
W3C公布最新的HTML5标准草案
2008/10/17 HTML / CSS
携程旅行网:中国领先的在线旅行服务公司
2017/02/17 全球购物
SEPHORA丝芙兰捷克官网:购买香水、化妆品和护肤品
2018/11/26 全球购物
个人作风剖析材料
2014/02/02 职场文书
房地产财务部员工岗位职责
2014/03/12 职场文书
食品安全承诺书范文
2014/08/29 职场文书
2014年质检工作总结
2014/11/26 职场文书
2016年“六一儿童节”校园广播稿
2015/12/17 职场文书