2021年更新
これは非常に古い問題でした。最近の JavaScript ははるかに寛容であり、元のソリューションは時代遅れになりました。JavaScript の改良により、jQuery もかなり時代遅れになりました。
この最初の投稿以来、フォント/バックエンド環境で JSON との間で配列、オブジェクト、さらにはネストされた両方の組み合わせをシリアル化するためのサポートが大幅に簡素化されました。
複雑なユーザー入力を送信するための次のオプションを見てください。
ネイティブ
JSON の操作
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON
JSON リクエスト オプションを使用したフェッチの例
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#supplying_request_options
アクシオス
fetch
ネイティブ ES6+ JavaScript の代替。Axios が配列とオブジェクトのシリアル化を処理します。
https://github.com/axios/axios
NodeJS
QueryString - プロジェクトでサポートされている場合、NodeJS からこのヘルパー クラスをインポートできます。
https://nodejs.org/api/querystring.html )
以下の古いコンテンツ
私にとってうまくいった解決策は、フォームの複数選択オプションからの多次元配列も処理できる独自の jQuery 関数 $.serializeAssoc() および $.serializeObject() の代替を作成することでした。
これら 2 つの機能には長所と短所があります。私は serializeAssoc を使用して、通常は JS Validation で一般的な値に直接アクセスするためにフォーム データを簡素化します。
serializeObject は、カスタム数値キー インデックスを使用する多機能フォームで便利です。複数選択フィールドの複雑なフォーム設定から送信された情報のデータ ペアリングや、フォーム内のデータが親子関係を持つ DOM によって構築された値を持つフォームを簡素化します。 serializeAssoc ではうまく処理できないものがあります。
serializeAssoc
次の関数は長さチェックを許可しますが、カスタム数値キー インデックスに問題があります。AJAX 呼び出しで配列を送信すると、インデックス パディングが発生します。
$.fn.serializeAssoc = function() {
var data = {};
$.each( this.serializeArray(), function( key, obj ) {
var a = obj.name.match(/(.*?)\[(.*?)\]/);
if(a !== null)
{
var subName = a[1];
var subKey = a[2];
if( !data[subName] ) {
data[subName] = [ ];
}
if (!subKey.length) {
subKey = data[subName].length;
}
if( data[subName][subKey] ) {
if( $.isArray( data[subName][subKey] ) ) {
data[subName][subKey].push( obj.value );
} else {
data[subName][subKey] = [ ];
data[subName][subKey].push( obj.value );
}
} else {
data[subName][subKey] = obj.value;
}
} else {
if( data[obj.name] ) {
if( $.isArray( data[obj.name] ) ) {
data[obj.name].push( obj.value );
} else {
data[obj.name] = [ ];
data[obj.name].push( obj.value );
}
} else {
data[obj.name] = obj.value;
}
}
});
return data;
};
serializeObject
次の関数は、パディングを発生させずにカスタム数値インデックスを許可しますが、長さチェックを防ぎます。必要に応じて、each ループを使用してインデックス キーの数を確認します。オブジェクトを AJAX 呼び出しで送信する場合、最初に JSON.Stringify を使用し、値を var に渡してサーバー側でデコードする必要があります。直接使用すると、一部のブラウザーで予期しない行末エラーが発生するためです。
$.fn.serializeObject = function() {
var data = {};
$.each( this.serializeArray(), function( key, obj ) {
var a = obj.name.match(/(.*?)\[(.*?)\]/);
if(a !== null)
{
var subName = new String(a[1]);
var subKey = new String(a[2]);
if( !data[subName] ) {
data[subName] = { };
data[subName].length = 0;
};
if (!subKey.length) {
subKey = data[subName].length;
}
if( data[subName][subKey] ) {
if( $.isArray( data[subName][subKey] ) ) {
data[subName][subKey].push( obj.value );
} else {
data[subName][subKey] = { };
data[subName][subKey].push( obj.value );
};
} else {
data[subName][subKey] = obj.value;
};
data[subName].length++;
} else {
var keyName = new String(obj.name);
if( data[keyName] ) {
if( $.isArray( data[keyName] ) ) {
data[keyName].push( obj.value );
} else {
data[keyName] = { };
data[keyName].push( obj.value );
};
} else {
data[keyName] = obj.value;
};
};
});
return data;
};
使用法:
機能の追加
<script>
(function($){
$.fn.serializeAssoc = function() {
... As Presented Above ...
};
$.fn.serializeObject = function() {
... As Presented Above ...
};
})(jQuery);
</script>
サンプルフォーム
<form id="myForm">
<input type="text" name="myName" />
<select name="consoles" multiple>
<option selected>PC</option>
<option selected>XBOX 360</option>
<option selected>PS3</option>
</select>
<input type="text" name="sample[100]" value="Mario" />
<input type="text" name="sample[101]" value="Brothers" />
<input type="submit" name="submit" value="Submit" />
</form>
機能の使用
<script>
(function($) {
$('#myForm').submit(function(e){
e.preventDefault();
var formData = $('#myForm').serializeAssoc();
console.log(formData);
});
})(jQuery);
</script>
動的フォームの例
<form id="myForm">
<input type="text" name="myName" value="Spuggy" />
<div id="characters">
<input type="text" name="character[]" value="Mario" />
<input type="text" name="character[]" value="Sonic" />
</div>
<div id="consoles">
<input type="text" name="console[xbox]" value="XBOX One" />
<input type="text" name="console[playstation]" value="PlayStation 4" />
</div>
<input type="submit" name="submit" value="Submit" />
</form>
<script>
(function($) {
$('#myForm').submit(function(e){
e.preventDefault();
var formData = $('#myForm').serializeAssoc();
console.log(formData);
});
})(jQuery);
</script>
動的フォーム出力
[
myName: 'Spuggy',
character: [
0: 'Mario',
1: 'Sonic'
],
console: [
'xbox': 'XBOX One',
'playstation': 'PlayStation 4'
]
]