Form表单自动转JSON对象、及解决AJAX调用时JSON对象数组成员key被修改问题

范培忠 2018-05-11

  本文讲解如何定义一个通用方法实现form表单内容自动打包成JSON对象用于AJAX提交,以及当form表单有checkbox时,该JSON对象会拥有一个成员数组提交到后台后会被“篡改”的问题(key name会被自动加一个中括号[]),JSON对象如下:

{"id":"998", "name":["臀部不放松","入定","杂念多"],"name2":["adsfasfas","2342 34r 23r"]),"option":"Option two"}

  一、form转JSON对象通用方法

  我们一般可以使用serializeArray()来组装用于AJAX提交的JSON对象。常见的写法如下:

function serializeFormToJSON() {
    formObject = {};
    x = $("form").serializeArray();
    $.each(x, function (i, field) {
        formObject[field.name] = field.value;
    });
    return formObject;
}

  但是如果当form表单里有一组checkbox或redio时会发生覆盖,我们需要将一组checkbox或redio的值序列化成数组对象。

  此外,还要在checkbox或radio没有任何选择时,生成一个空值,否则容易导致后端获取数据时报错。

  优化的写法如下:

$.fn.serializeObject = function () {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function () {
        if (o[this.name] !== undefined) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    var $radio = $('input[type=radio],input[type=checkbox]',this);
    $.each($radio,function(){
        if(!o.hasOwnProperty(this.name)){
            o[this.name] = '';
        }
    });
    return o;
};

  可以使用如下方式访问:

function prepareForm() {
    var obj = $("form").serializeObject();
    console.log(obj);
}

  实际效果就是这样(name和name2是两组checkbox,option是一组radio):


  用字符串形式表示该JSON对象就是本文开头的那个形式:

{"id":"较舒服", "name":["臀部不放松","入定","杂念多"],"name2":["adsfasfas","2342 34r 23r"]),"option":"Option two"}

  那么此时使用AJAX设置为data直接上传就会出现诡异的问题。

  二、JSON对象数组成员AJAX提交到后台key被“篡改”问题的解决

  为什么说JSON对象数组成员在使用AJAX提交到后台后,key会被“篡改”呢,如下图所示:


  我在控制器方法上打了个断点,可以看见传入的JSON字串,key为“name”的键值对已经被篡改成了key为“name[]”,增加一对中括号,导致按名称解析参数时无法正确地获取信息。

  这也就是AJAX调用组织数据是,只要遇到有checkbox时(checkbox的多选值会被处理成一个数组成员)就需要单独进行stringify的原因,不然就会出错。已然形成“潜规则”。一般的写法如下:

data: {"id":"较舒服", "name":JSON.stringify(["臀部不放松","入定","杂念多"]),"name2":JSON.stringify(["adsfasfas","2342 34r 23r"]),"option":"Option two"},

  至于解决方法也很简单,jQuery的AJAX方法还有一项属性叫做traditional,将它设置为true就可以避免JSON数组的深度序列化。就不用单独对数组调用stringify了。

$.ajax({
    type: "post",
    traditional:true,
    //以下省略...

  参考资料:

  https://segmentfault.com/a/1190000006154289

  https://www.cnblogs.com/william-lin/p/4409891.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值