基于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 相关文章推荐
js Date概念详细介绍
Nov 22 Javascript
Jquery下EasyUI组件中的DataGrid结果集清空方法
Jan 06 Javascript
AngularJS基础 ng-disabled 指令详解及简单示例
Aug 01 Javascript
Angular中$state.go页面跳转并传递参数的方法
May 09 Javascript
Angular实现搜索框及价格上下限功能
Jan 19 Javascript
详解JSON Web Token 入门教程
Jul 30 Javascript
原生js添加一个或多个类名的方法分析
Jul 30 Javascript
创建nuxt.js项目流程图解
Mar 13 Javascript
JS猜数字游戏实例讲解
Jun 30 Javascript
Vue+Bootstrap收藏(点赞)功能逻辑与具体实现
Oct 22 Javascript
react+antd 递归实现树状目录操作
Nov 02 Javascript
一行JavaScript代码如何实现瀑布流布局
Dec 11 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 500报错的快速解决方法
2016/12/14 PHP
PHP消息队列实现及应用详解【队列处理订单系统和配送系统】
2019/05/20 PHP
PHP操作Redis常用命令的实例详解
2020/12/23 PHP
javascript 计算两个整数的百分比值
2009/12/26 Javascript
8个实用的jQuery技巧
2014/03/04 Javascript
开发中可能会用到的jQuery小技巧
2014/03/07 Javascript
三种检测iPhone/iPad设备方向的方法
2014/04/23 Javascript
纯js和css实现渐变色包括静态渐变和动态渐变
2014/05/29 Javascript
jQuery隐藏和显示效果实现
2016/04/06 Javascript
js实现人民币大写金额形式转换
2016/04/27 Javascript
浅谈js中的in-for循环
2016/06/28 Javascript
jQuery 选择符详细介绍及整理
2016/12/02 Javascript
进阶之初探nodeJS
2017/01/24 NodeJs
推荐三款不错的图片压缩上传插件(webuploader、localResizeIMG4、LUploader)
2017/04/21 Javascript
微信小程序上传图片实例
2018/05/28 Javascript
cdn模式下vue的基本用法详解
2018/10/07 Javascript
JS实现随机生成10个手机号的方法示例
2018/12/07 Javascript
基于JavaScript或jQuery实现网站夜间/高亮模式
2020/05/30 jQuery
Element Backtop回到顶部的具体使用
2020/07/27 Javascript
vue监听浏览器原生返回按钮,进行路由转跳操作
2020/09/09 Javascript
[49:05]Newbee vs TNC 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python中字典的浅拷贝与深拷贝用法实例分析
2018/01/02 Python
Python将多个excel表格合并为一个表格
2021/02/22 Python
PyQt5每天必学之事件与信号
2018/04/20 Python
selenium在执行phantomjs的API并获取执行结果的方法
2018/12/17 Python
selenium+python自动化测试之使用webdriver操作浏览器的方法
2019/01/23 Python
解决python中画图时x,y轴名称出现中文乱码的问题
2019/01/29 Python
Python利用lxml模块爬取豆瓣读书排行榜的方法与分析
2019/04/15 Python
PyTorch-GPU加速实例
2020/06/23 Python
HTML5 的新的表单元素(datalist/keygen/output)使用介绍
2013/07/19 HTML / CSS
美国孕妇装购物网站:Motherhood Maternity
2019/09/22 全球购物
Yankee Candle官网:美国最畅销蜡烛品牌之一
2020/01/05 全球购物
自主招生自荐信指南
2014/02/04 职场文书
省级优秀毕业生主要事迹
2014/05/29 职场文书
2016领导干部廉洁自律心得体会
2016/01/13 职场文书
MYSQL 表的全面总结
2021/11/11 MySQL