基于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 相关文章推荐
jquery多浏览器捕捉回车事件代码
Jun 22 Javascript
jQuery中queue()方法用法实例
Dec 29 Javascript
jquery插件corner实现圆角边框的方法
Mar 09 Javascript
详解JavaScript数组的操作大全
Oct 19 Javascript
下一代Bootstrap的5个特点 超酷炫!
Jun 17 Javascript
浅谈React中的元素、组件、实例和节点
Feb 27 Javascript
webpack本地开发环境无法用IP访问的解决方法
Mar 20 Javascript
vue select选择框数据变化监听方法
Aug 24 Javascript
自定义javascript验证框架示例【附源码下载】
May 31 Javascript
js实现鼠标点击页面弹出自定义文字效果
Dec 24 Javascript
es6中使用map简化复杂条件判断操作实例详解
Feb 19 Javascript
微信小程序后端实现授权登录
Feb 24 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
全国FM电台频率大全 - 26 西藏自治区
2020/03/11 无线电
PHP Global定义全局变量使用说明
2013/08/15 PHP
php采用file_get_contents代替使用curl实例
2014/11/07 PHP
phpStudy中升级MySQL版本到5.7.17的方法步骤
2017/08/03 PHP
各情景下元素宽高的获取实现代码
2011/09/13 Javascript
简洁Ajax函数处理(示例代码)
2013/11/15 Javascript
jq实现酷炫的鼠标经过图片翻滚效果
2014/03/12 Javascript
js焦点文字滚动效果代码分享
2015/08/25 Javascript
jquery+CSS3实现淘宝移动网页菜单效果
2015/08/31 Javascript
利用jQuery实现漂亮的圆形进度条倒计时插件
2015/09/30 Javascript
javascript实现移动端上的触屏拖拽功能
2016/03/04 Javascript
JavaScript编写检测用户所使用的浏览器的代码示例
2016/05/05 Javascript
详解js中常规日期格式处理、月历渲染和倒计时函数
2016/12/28 Javascript
Angular2数据绑定详解
2017/04/18 Javascript
详解vue组件通信的三种方式
2017/06/30 Javascript
详解IWinter 一个路由转控制器的 Nodejs 库
2017/11/15 NodeJs
CKEditor4配置与开发详细中文说明文档
2018/10/08 Javascript
如何阻止小程序遮罩层下方图层滚动
2019/09/05 Javascript
浅谈用Python实现一个大数据搜索引擎
2017/11/28 Python
python处理csv数据动态显示曲线实例代码
2018/01/23 Python
python接口调用已训练好的caffe模型测试分类方法
2019/08/26 Python
执行Django数据迁移时报 1091错误及解决方法
2019/10/14 Python
通过实例简单了解Python中yield的作用
2019/12/11 Python
python图片剪裁代码(图片按四个点坐标剪裁)
2020/03/10 Python
python和pywin32实现窗口查找、遍历和点击的示例代码
2020/04/01 Python
sklearn中的交叉验证的实现(Cross-Validation)
2021/02/22 Python
Belle Maison倍美丛官网:日本千趣会旗下邮购网站
2016/07/22 全球购物
南非最受欢迎的时尚品牌:MRP
2016/09/18 全球购物
Camper鞋西班牙官方网上商店:西班牙马略卡岛的鞋类品牌
2019/03/14 全球购物
世界上最伟大的马产品:Equiderma
2020/01/07 全球购物
年度考核自我鉴定
2013/11/09 职场文书
降消项目实施方案
2014/03/30 职场文书
感恩教育月活动总结
2014/07/07 职场文书
2015驻村干部工作总结
2015/04/07 职场文书
2015年班组工作总结
2015/04/20 职场文书
Python Numpy之linspace用法说明
2021/04/17 Python