Javascript将表单序列化为对象

Javascript将表单序列化为对象,javascript,forms,serialization,Javascript,Forms,Serialization,我有一个名为'config[display][x]'、'config[display][y]'、'config[port]'、…的表单,或者我可以创建不同的格式。 我想把它序列化为JS对象,比如 {config: display : {x : 'value', y : 'value'}, port : 'value' } 有人知道现有的解决方案吗 p、 我可以用jQuery的.serializeArray()序列化表单,但我将使用简单的{name:name,value:valu

我有一个名为
'config[display][x]'、'config[display][y]'、'config[port]'、…
的表单,或者我可以创建不同的格式。 我想把它序列化为JS对象,比如

{config:
    display : {x : 'value', y : 'value'},
    port : 'value'
}
有人知道现有的解决方案吗


p、 我可以用jQuery的.serializeArray()序列化表单,但我将使用简单的{name:name,value:value}散列数组。但是如何创建对象?

要将JavaScript对象序列化为字符串,请使用:

var str = JSON.stringify(obj);
要将字符串反序列化为JavaScript对象,请使用:

var obj = JSON.parse(str);

如果您使用的是不支持这些方法的旧浏览器,则可以使用Douglas Crockford提供的库。

我使用了Ben Almans
.serializeObject()
,它工作正常

代码小而简单:

$.fn.serializeObject = function(){
    var obj = {};

    $.each( this.serializeArray(), function(i,o){
        var n = o.name,
        v = o.value;

        obj[n] = obj[n] === undefined ? v
            : $.isArray( obj[n] ) ? obj[n].concat( v )
            : [ obj[n], v ];
    });

    return obj;
};

我相信这就是你所追求的:

function assignByPath(obj,path,value){
    if (path.length == 1) {
        obj[path[0]] = value;
        return obj;
    } else if (obj[path[0]] === undefined) {
        obj[path[0]] = {};
    } 
    return assignByPath(obj[path.shift()],path,value);
}

$.fn.serializeObject = function(){
    var obj = {};

    $.each( this.serializeArray(), function(i,o){
        var n = o.name,
        v = o.value;
        path = n.replace('[','.').replace('][','.').replace(']','').split('.');

        assignByPath(obj,path,v);
    });

    return obj;
};
请参阅-还与现有解决方案进行了比较

var myFormObj = formToObject('myFormId');
/* 
  console.log(myFormObj);
  {
    saveSettings: 'Save',
    name: 'Serban',
    race: 'orc',
    settings: {
       input: 'keyboard',
       video: {
          resolution: '1024x768',
          vsync: 'on'
       }
    }
  }
*/

这就是我使用嵌套表单名的方法,它可以有多个层,这取决于我必须传输的内容。我只需要在边缘的情况下,但我想我会在这里分享这个

我有一个问题,表单名作为
数据[SomeName[hello]][world]=“foobar”
提交,这将导致php上的数据结构糟糕(例如)

在提交我只用于的序列化数据之前,没有检查数据客户端,当表单数据被包装到另一个对象中时,我得到了这些错误

通过在下面的代码片段中检查代码,我解决了这个问题,并且能够发送一个完整有效的数据结构

getFormData=函数($form)
{    	
var paramObj={};
/**
*信用到期时的信用。复制自https://stackoverflow.com/a/48218209/1356107 杰尔登比德尔
*/
var mergeDeep=函数(…对象)
{
var isObject=obj=>obj&&typeof obj==='object';
返回对象。减少((上一个,对象)=>{
Object.keys(obj.forEach)(key=>{
var pVal=上一个[关键];
var oVal=obj[键];
if(Array.isArray(pVal)和&Array.isArray(oVal)){
上一个[键]=pVal.concat(…椭圆形);
}
其他if(等高线(pVal)和等高线(椭圆形)){
prev[key]=mergeDeep(pVal,椭圆形);
}
否则{
前[键]=椭圆形;
}
});
返回上一个;
}, {});
}
var phpFormKeyToObject=函数(键,值)
{
var lookup=key.indexOf('[');
如果(查找!=-1){
var arrayName=key.substring(0,查找);
var newObj={};
newObj[arrayName]={};
var res=key.matchAll(/\[(.*?)\]/g);
var-previous=newObj[arrayName];
var lastkey=arrayName;
var lastobj=newObj;
for(res的var匹配){
/** 
*数组提前退出。零长度键是array、append和exit。
*/
if(匹配[1]。长度==0){
if(Array.isArray(lastobj[lastkey])){
lastobj[lastkey].push(值);
返回newObj;
}
否则{
lastobj[lastkey]=[value];
返回newObj;
}
}
否则{
先前的[匹配[1]]={};
lastobj=先前的;
上一个=上一个[匹配[1]];
lastkey=匹配[1];
}
}
lastobj[lastkey]=值;
返回newObj;
}
返回false;
}
/** 
*信用到期时的信用,稍微修改版本的https://stackoverflow.com/a/2403206/1356107 尖刻地
*/  
$.each($form.serializeArray(),函数(\ukV){
if(kv.name.indexOf('[')!=-1){
var obj=phpFormKeyToObject(千伏名称,千伏值);
paramObj=mergeDeep(paramObj,obj);
}
否则{
if(paramObj.hasOwnProperty(kv.name)){
paramObj[kv.name]=$.makeArray(paramObj[kv.name]);
paramObj[kv.name].push(kv.value);
}
否则{
paramObj[kv.name]=kv.value;
}
}
});
返回paramObj;
}

检查它1
检查它2
检查它3
测试
额外的1英镑要多少钱 1. 2. 3.
额外的2英镑要多少钱 1. 2. 3.

和?表单名称-仅字符串这无法正确序列化数组和嵌套属性。目前,如果您想使用数组,则会遇到障碍。@Xr.同意,这就是我决定拆分库并对其进行单元测试的原因。我需要回归来修复此问题。我需要解决此问题,因为在JavaScript中,无法使用带字符串的数组艾尔·凯斯。谢谢你的反馈!对于其他错过的人,扎克的回答是一个很好的候选人。
$data = [
   "data" => [
     "SomeName[hello" => [
         "world" => "foobar"
     ],
  ],
];