如何将jQuery.serialize()数据转换为JSON对象?

Raf*_*lks 44 javascript jquery serialization json

当表单包含多个输入数组字段时,是否有更好的解决方案来转换已经由jQuery函数serialize()序列化的表单数据.我希望能够将表单数据转换为JSON对象以重新创建一些其他信息表.所以告诉我一个更好的方法来将序列化字符串转换为JSON对象.

<form id='sampleform'>
    <input name='MyName' type='text' /> // Raf

    <!--array input fields below-->
    <input name='friendname[]' type='text' /> // Bily
    <input name='fiendemail[]' type='text' /> // bily@someemail.com

    <!--duplicated fields below to add more friends -->
    <input name='friendname[]' type='text' /> // Andy
    <input name='fiendemail[]' type='text' /> // Andy@somwhere.com

    <input name='friendname[]' type='text' /> // Adam
    <input name='fiendemail[]' type='text' /> // Adam@herenthere.com
</form>
Run Code Online (Sandbox Code Playgroud)

应用jquery方法获取数据

var MyForm = $("#sampleform").serialize();
/** result : MyName=Raf&friendname[]=Billy&fiendemail[]=bily@someemail.com&friendname[]=Andy&fiendemail[]=Andy@somwhere.com&friendname[]=Adam&fiendemail[]=Adam@herenthere.com
*/
Run Code Online (Sandbox Code Playgroud)

如何将此数据转换为JSON对象?它应该具有以下来自上述表单的示例JSON数据.

{
    "MyName":"raf",
    "friendname":[
        {"0":"Bily"},
        {"1":"Andy"},
        {"2":"Adam"}
    ],
    "friendemail":[
        {"0":"bily@someemail.com"},
        {"1":"Andy@somwhere.com"},
        {"2":"Adam@herenthere.com"}
    ]
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*sso 50

var formdata = $("#myform").serializeArray();
var data = {};
$(formdata ).each(function(index, obj){
    data[obj.name] = obj.value;
});
Run Code Online (Sandbox Code Playgroud)

简单快速;)

  • 这不会生成分层的JS对象 (6认同)
  • **警告**:如果你有多个具有相同键的值(在表单中允许),这将不会保留它们并覆盖同名的值 (3认同)
  • @Epoc你指的是什么样的层次结构概念?表格数据持平. (2认同)

Sam*_*ham 12

我最近遇到了这个问题.最初,我们使用jQuery的serializeArray()方法,但不包括禁用的表单元素.我们经常会禁用与页面上其他来源"同步"的表单元素,但我们仍然需要将数据包含在序列化对象中.好serializeArray()了.我们使用:input选择器获取给定容器中的所有输入元素(启用和禁用),然后$.map()创建我们的对象.

var inputs = $("#container :input");
var obj = $.map(inputs, function(n, i)
{
    var o = {};
    o[n.name] = $(n).val();
    return o;
});
console.log(obj);
Run Code Online (Sandbox Code Playgroud)

请注意,为此,每个输入都需要一个name属性,该属性将是结果对象的属性名称.

实际上,这与我们使用的内容略有不同.我们需要创建一个结构为.NET IDictionary的对象,所以我们使用了这个:(我在这里提供它,以防它有用)

var obj = $.map(inputs, function(n, i)
{
    return { Key: n.name, Value: $(n).val() };
});
console.log(obj);
Run Code Online (Sandbox Code Playgroud)

我喜欢这两种解决方案,因为它们是$.map()函数的简单用法,并且您可以完全控制选择器(因此,最终包含在结果对象中的元素).此外,不需要额外的插件.简单的旧jQuery.

  • 我认为你的map函数不太正确...你为每个属性返回一个单独的对象...不要'你想把所有属性放在一个对象上吗?...所以声明对象在函数外面,而不是在里面(并且不要返回任何内容 - 仅使用地图进行副作用) (2认同)

tot*_*rio 7

使用jQuery.serializeJSON插件.它使用与在Rails params对象中找到的格式相同的格式转换表单,这是非常标准且经过充分测试的.


S.C*_*.C. 5

我正在使用这个非常小的jQuery插件,我从DocumentCloud扩展了:

https://github.com/documentcloud/documentcloud/blob/master/public/javascripts/lib/jquery_extensions.js

它基本上是两行代码,但它需要_.js(Underscore.js),因为它基于一个reduce函数.

$.fn.extend({
  serializeJSON: function(exclude) {
    exclude || (exclude = []);
    return _.reduce(this.serializeArray(), function(hash, pair) {
      pair.value && !(pair.name in exclude) && (hash[pair.name] = pair.value);
      return hash;
    }, {});
  }
});
Run Code Online (Sandbox Code Playgroud)

扩展:

  • 如果输入值为null,则不会序列化输入值
  • 它可以通过将一组输入名称传递给exclude参数来排除某些输入i.e. ["password_confirm"]


Sim*_*eau 5

我认为这里有很多很好的答案,我根据这些答案制作了自己的函数。

function formToJSON(f) {
    var fd = $(f).serializeArray();
    var d = {};
    $(fd).each(function() {
        if (d[this.name] !== undefined){
            if (!Array.isArray(d[this.name])) {
                d[this.name] = [d[this.name]];
            }
            d[this.name].push(this.value);
        }else{
            d[this.name] = this.value;
        }
    });
    return d;
}

//The way to use it :
$('#myForm').submit(function(){
    var datas = formToJSON(this);
    return false;
});
Run Code Online (Sandbox Code Playgroud)

好吧,让我基本上解释一下为什么我更喜欢这个解决方案......如果你有多个同名输入,所有值都将存储在一个数组中,但如果没有,该值将直接存储为 JSON 中的索引值...这是它与Danilo Colasso 的答案不同地方,其中返回的 JSON 仅基于数组值...

因此,如果您有一个名为content和多个作者的文本区域的表单,则此函数将返回给您:

{
    content : 'This is The Content',
    authors : 
        [
            0: 'me',
            1: 'you',
            2: 'him',
        ]
}
Run Code Online (Sandbox Code Playgroud)


小智 5

如果你可以使用 ES6,你可以这样做

const obj = arr.reduce((acc, {name, value}) => ({...acc, [name]: value}), {})
Run Code Online (Sandbox Code Playgroud)

对于序列化数组效果很好。