web-dev-qa-db-ja.com

ネストされたFormDataをAJAX

ファイルとその他のパラメーターを送信したいので、ajaxとFormDataを使用してデータを送信する必要があります。私が通常データを送信する方法はこれです:

$.ajax({
    type:       'POST',
    url:        'some_url',
    dataType:   'json',
    processData:false,
    contentType:false,
    data:{
        Lvl_1-1: 'something',
        Lvl_1-2: 'something',
        Lvl_1-3: {
            Lvl_1-3-1: "something",
            Lvl_1-3-2: "something",
            Lvl_1-3-3: "something",
        },
    },
    ...
});

FormData()を使用しない場合は問題ありませんが、FormData()を使用すると、Lvl1のデータのみが問題ありませんが、ネストされたものはすべてこのように文字列として表示されます

<b>array</b> <i>(size=3)</i>
    'Lvl1-1' <font color='#888a85'>=&gt;</font> <small>string</small> 
        <font color='#cc0000'>'Something'</font> 
        <i>(length=23)</i>
    'Lvl1-2' <font color='#888a85'>=&gt;</font> <small>string</small> 
        <font color='#cc0000'>''Something''</font> <i>(length=3)</i>
    'Lvl1-3' <font color='#888a85'>=&gt;</font> <small>string</small> 
        <font color='#cc0000'>'[object Object]'</font> <i>(length=17)</i>

FormData()を使用して[object Object]の代わりにLvl1-3内のデータをエンコードすると、[object FormData]が得られます

Lvl1-3で文字列ではなく配列を取得するにはどうすればよいですか?

注:ファイルが最上位(Lvl_1)にある場合、FormData()を使用して問題なくファイルを送信できます。添付ファイルのコードは書きませんでした。それは問題ではなく、ネストされたデータが問題だからです。私がFormData()を使用しているのはそのためです。

15
kunde

URLエンコードされたフォームデータには、複雑なデータ構造を表現するネイティブな方法がありません。単純なキー=値のペアのみをサポートします。

?foo=1&bar=2

ほとんどのフォームデータ解析ライブラリでは、同じ名前のキーを使用してデータの配列を使用できます

?foo=1&foo=2

PHPは独自の構文をその形式に加えました。

?foo[]=1&foo[]=2

連想配列で名前付きキーを使用できます。

?foo[bar]=1&foo[baz]=2

ネストされた配列:

?foo[bar][level2a]=1&foo[bar][level2b]=2

PHPの普及により、jQueryはJavaScriptオブジェクトをdataに渡すときにフォームデータを生成するためにその構文を採用しました。

FormDataを使用する場合、jQueryはそれを再処理しません。

表示されている効果は、appendの2番目の引数としてオブジェクトを配置しようとしているためです(私はFormDataインスタンスを推測していますが、コードのその部分は示していません)。期待されています。

PHPの構文を使用して、自分でキー名を生成する必要があります。

form_data_instance.append("Lvl_1-3[Lvl_1-3-1]", "something");
form_data_instance.append("Lvl_1-3[Lvl_1-3-2]", "something");
form_data_instance.append("Lvl_1-3[Lvl_1-3-3]", "something");
18
Quentin

私の端では、ネストされたパラメーターを文字列化し、もう一方の端でそれらを解析します。

たとえば、渡したい場合:

{"sthing":
  {"sthing":"sthing"},
  {"picture":
    {"legend":"great legend"},
    {"file":"great_picture.jpg"}
  }
}

それから私はします:

// On the client side
const nestedParams = {"sthing":
                       {"sthing":"sthing"},
                       {"picture":
                         {"legend":"great legend"}
                       }
                     };
const pictureFile = document.querySelector('input[type="file"]')[0];
const formDataInstance = new FormData;
formDataInstance.append("nested_params": JSON.stringify(nested_params);
formDataInstance.append("file": document.querySelector('input[type="file"]')[0]);


// On the server side
params["nested_params"] = JSON.parse(params["nested_params"]);
params["nested_params"]["sthing"]["picture"]["file"] = params["file"];
7
Cedric