基于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(JS) 压缩 / 混淆 / 格式化 批处理工具
Dec 10 Javascript
简短几句jquery代码的实现一个图片向上滚动切换
Sep 02 Javascript
JavaScript实现拼音排序的方法
Nov 20 Javascript
js实现目录定位正文示例
Nov 14 Javascript
文本框倒叙输入让输入框的焦点始终在最开始的位置
Sep 01 Javascript
jQuery实现页面顶部显示的进度条效果完整实例
Dec 09 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
Jun 02 Javascript
JavaScript ES6的新特性使用新方法定义Class
Jun 28 Javascript
JavaScript基于DOM操作实现简单的数学运算功能示例
Jan 16 Javascript
vue如何根据网站路由判断页面主题色详解
Nov 02 Javascript
VUE v-model表单数据双向绑定完整示例
Jan 21 Javascript
使用vue中的混入mixin优化表单验证插件问题
Jul 02 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
解析使用substr截取UTF-8中文字符串出现乱码的问题
2013/06/20 PHP
PHP模板引擎Smarty自定义变量调解器用法
2016/04/11 PHP
php封装的验证码类分享
2017/02/26 PHP
PHP判断是否是微信打开还是浏览器打开的方法
2019/02/27 PHP
js本身的局限性 别让javascript做太多事
2010/03/23 Javascript
jquery命令汇总,方便使用jquery的朋友
2012/06/26 Javascript
jQuery(js)获取文字宽度(显示长度)示例代码
2013/12/31 Javascript
纯javascript实现分页(两种方法)
2015/08/26 Javascript
json与jsonp知识小结(推荐)
2016/08/16 Javascript
Vue.js每天必学之组件与组件间的通信
2016/09/08 Javascript
javascript判断firebug是否开启的方法
2016/11/23 Javascript
新闻上下滚动jquery 超简洁(必看篇)
2017/01/21 Javascript
基于Nodejs利用socket.io实现多人聊天室
2017/02/22 NodeJs
nodejs之get/post请求的几种方式小结
2017/07/26 NodeJs
ES6扩展运算符用法实例分析
2017/10/31 Javascript
layui 上传文件_批量导入数据UI的方法
2019/09/23 Javascript
[01:03:41]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第三场 2月2日
2021/03/11 DOTA
python实现控制台打印的方法
2019/01/12 Python
python flask解析json数据不完整的解决方法
2019/05/26 Python
pytorch加载自定义网络权重的实现
2020/01/07 Python
Python GUI编程学习笔记之tkinter控件的介绍及基本使用方法详解
2020/03/30 Python
详解如何通过H5(浏览器/WebView/其他)唤起本地app
2017/12/11 HTML / CSS
美体小铺波兰官方网站:The Body Shop波兰
2019/09/03 全球购物
先进事迹报告会感言
2014/01/24 职场文书
汽车运用工程专业求职信
2014/06/18 职场文书
平面设计专业求职信
2014/08/09 职场文书
公司的门卫岗位职责
2014/09/09 职场文书
超市开店计划书
2014/09/15 职场文书
2014县政府领导班子三严三实对照检查材料思想汇报
2014/09/26 职场文书
团队会宣传标语
2014/10/09 职场文书
党的群众路线教育实践活动个人对照检查材料(乡镇)
2014/11/05 职场文书
2014年教师个人工作总结
2014/11/10 职场文书
在校学生证明格式
2015/06/24 职场文书
2016党员学习心得体会范文
2016/01/23 职场文书
MySQL 常见的数据表设计误区汇总
2021/06/07 MySQL
Element-ui Layout布局(Row和Col组件)的实现
2021/12/06 Vue.js