基于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 播放器 控制
Jan 22 Javascript
JavaScript DOM学习第六章 表单实例
Feb 19 Javascript
javascript+iframe 实现无刷新载入整页的代码
Mar 17 Javascript
Javascript学习笔记一 之 数据类型
Dec 15 Javascript
jquery 提交值不为空的元素示例代码
May 10 Javascript
Ext JS 4实现带week(星期)的日期选择控件(实战二)
Aug 21 Javascript
jQuery实现可展开合拢的手风琴面板菜单
Sep 15 Javascript
JavaScript实现清空(重置)文件类型INPUT元素值的方法
Nov 17 Javascript
jQuery实现的简单排序功能示例【冒泡排序】
Jan 13 Javascript
关于vue面试题汇总
Mar 20 Javascript
详解Vue中使用插槽(slot)、聚类插槽
Apr 12 Javascript
微信小程序自定义纯净模态框(弹出框)的实例代码
Mar 09 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
Terran魔法科技
2020/03/14 星际争霸
PHP获取php,mysql,apche的版本信息示例代码
2014/01/16 PHP
php实现文件下载简单示例(代码实现文件下载)
2014/03/10 PHP
Laravel框架学习笔记(二)项目实战之模型(Models)
2014/10/15 PHP
如何在HTML 中嵌入 PHP 代码
2015/05/13 PHP
php抛出异常与捕捉特定类型的异常详解
2016/10/26 PHP
PHP单例模式应用示例【多次连接数据库只实例化一次】
2018/12/18 PHP
php无限极分类实现方法分析
2019/07/04 PHP
JQuery this 和 $(this) 的区别
2009/08/23 Javascript
jquery中dom操作和事件的实例学习-表单验证
2011/11/30 Javascript
经过绑定元素时会多次触发mouseover和mouseout事件
2014/02/28 Javascript
原生js事件的添加和删除的封装
2014/07/01 Javascript
jQuery 操作input中radio的技巧
2016/07/18 Javascript
开发Vue树形组件的示例代码
2017/12/21 Javascript
Vue+mui实现图片的本地缓存示例代码
2018/05/24 Javascript
详解vue-cli项目中怎么使用mock数据
2018/05/29 Javascript
MVVM 双向绑定的实现代码
2018/06/21 Javascript
JavaScript实现图片上传并预览并提交ajax
2019/09/30 Javascript
vue解决使用$http获取数据时报错的问题
2019/10/30 Javascript
微信小程序swiper使用网络图片不显示问题解决
2019/12/13 Javascript
Vue+webpack实现懒加载过程解析
2020/02/17 Javascript
微信小程序实现组件顶端固定或底端固定效果(不随滚动而滚动)
2020/04/09 Javascript
pycharm 使用心得(七)一些实用功能介绍
2014/06/06 Python
为Python的web框架编写前端模版的教程
2015/04/30 Python
Python3解决棋盘覆盖问题的方法示例
2017/12/07 Python
在Pandas中给多层索引降级的方法
2018/11/16 Python
Python selenium根据class定位页面元素的方法
2019/02/26 Python
python把1变成01的步骤总结
2019/02/27 Python
Django保护敏感信息的方法示例
2019/05/09 Python
python中for循环变量作用域及用法详解
2019/11/05 Python
Python Tensor FLow简单使用方法实例详解
2020/01/14 Python
马来西亚最好的婴儿商店:Motherhood
2017/09/14 全球购物
高尔夫球鞋、服装、手套和装备:FootJoy
2018/12/15 全球购物
UNIX文件名称有什么规定
2013/03/25 面试题
励志演讲稿范文
2014/04/29 职场文书
穆斯林的葬礼读书笔记
2015/06/26 职场文书