基于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 相关文章推荐
textContent在Firefox下与innerText等效的属性
May 12 Javascript
jquery 插件 人性化的消息显示
Jan 21 Javascript
使用JavaScript 实现各种跨域的方法
May 08 Javascript
Jquery Ajax解析XML数据(同步及异步调用)简单实例
Feb 12 Javascript
简介JavaScript中POSITIVE_INFINITY值的使用
Jun 05 Javascript
Jquery检验手机号是否符合规则并根据手机号检测结果将提交按钮设为不同状态
Nov 26 Javascript
js实现前端分页页码管理
Jan 06 Javascript
JS中promise化微信小程序api
Apr 12 Javascript
在Vue 中使用Typescript的示例代码
Sep 10 Javascript
jQuery实现数字华容道小游戏(实例代码)
Jan 16 jQuery
vue element-ul实现展开和收起功能的实例代码
Nov 25 Vue.js
基于Vue2实现移动端图片上传、压缩、拖拽排序、拖拽删除功能
Jan 05 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利用header函数实现文件下载时直接提示保存
2009/11/12 PHP
PHP调用C#开发的dll类库方法
2014/07/28 PHP
IE和Mozilla的兼容性汇总event
2007/08/12 Javascript
javascript Array.sort() 跨浏览器下需要考虑的问题
2009/12/07 Javascript
jQuery效果 slideToggle() 方法(在隐藏和显示之间切换)
2011/06/28 Javascript
如何让页面在打开时自动刷新一次让图片全部显示
2012/12/17 Javascript
使用insertAfter()方法在现有元素后添加一个新元素
2014/05/28 Javascript
点击button获取text内容并改变样式的js实现
2014/09/09 Javascript
jQuery中removeClass()方法用法实例
2015/01/05 Javascript
JavaScript电子时钟倒计时第二款
2016/01/10 Javascript
AngularJS双向绑定和依赖反转实例详解
2017/04/15 Javascript
webpack学习教程之publicPath路径问题详解
2017/06/17 Javascript
JS实现的按钮点击颜色切换功能示例
2017/10/19 Javascript
使用layui实现的左侧菜单栏以及动态操作tab项方法
2019/09/10 Javascript
详解JavaScript类型判断的四种方法
2020/10/21 Javascript
Python和JavaScript间代码转换的4个工具
2016/02/22 Python
Python 常用的安装Module方式汇总
2017/05/06 Python
python编程嵌套函数实例代码
2018/02/11 Python
tensorflow实现简单的卷积神经网络
2018/05/24 Python
基于python代码实现简易滤除数字的方法
2018/07/17 Python
Python pygorithm模块用法示例【常见算法测试】
2018/08/16 Python
一行Python代码制作动态二维码的实现
2019/09/09 Python
win10下python2和python3共存问题解决方法
2019/12/23 Python
python 的numpy库中的mean()函数用法介绍
2020/03/03 Python
python 一维二维插值实例
2020/04/22 Python
Python使用sys.exc_info()方法获取异常信息
2020/07/23 Python
HTML5的Video标签有部分MP4无法播放的问题解析(多图)
2017/08/18 HTML / CSS
约瑟夫·特纳男装:Joseph Turner
2017/10/10 全球购物
网络工程师专家职业发展路线
2014/02/14 职场文书
红色电影观后感
2015/06/18 职场文书
红楼梦读书笔记
2015/06/25 职场文书
2016年领导干部廉政承诺书
2016/03/24 职场文书
2019员工保密协议书(3篇)
2019/09/23 职场文书
CSS 新特性 contain控制页面的重绘与重排问题
2021/04/30 HTML / CSS
JDBC连接的六步实例代码(与mysql连接)
2021/05/12 MySQL
详解Python生成器和基于生成器的协程
2021/06/03 Python