prosource

FormData 중첩된 개체 추가

probook 2023. 3. 14. 21:44
반응형

FormData 중첩된 개체 추가

중첩된 개체를 에 추가할 수 있습니까?FormData?

let formData = new FormData();
let data = {
    title: 'title',
    text: 'text',
    preview: {p_title:'p title', p_text: 'p text'}
};

$.each(data, function(key, value) {
    formData.append(key, value);
});

서버 콘솔 - console.log(req.body)

{
    title: 'title',
    text: 'text',
    preview: '[object Object]'
}

어떻게 하면 정확한 값을 얻을 수 있을까요?preview: {p_title:'p title', p_text: 'p text'}?

let formData = new FormData();
let data = {
  title: 'title',
  text: 'text',
  preview: {p_title:'p title', p_text: 'p text'}
};

for(let dataKey in data) {
  if(dataKey === 'preview') {
    // append nested object
    for (let previewKey in data[dataKey]) {
      formData.append(`preview[${previewKey}]`, data[dataKey][previewKey]);
    }
  }
  else {
    formData.append(dataKey, data[dataKey]);
  }
}

콘솔 폼 데이터

for (let val of formData.entries()) {
  console.log(val[0]+ ', ' + val[1]); 
}

개체를 formData에 추가하려면 먼저 다음과 같이 문자열을 지정해야 합니다.

let objToAppend= {
  key1: value1,
  key2: value2,
}
let formData = new FormData();
formData.append('obj', JSON.stringify(objToAppend));

그런 다음 서버 측에서 액세스하려면 먼저 다음을 사용하여 해석해야 합니다.JSON.parse()도움이 됐으면 좋겠네요!

우선 영어가 서툴러서 죄송합니다.

콘솔에 쓸 때가 아니라 서버 측에서 데이터를 제대로 얻기 위해 작업을 했습니다.네가 이걸 하고 싶어했으면 좋겠어.

서버 측에서 클라이언트 측의 중첩된 데이터를 얻기 위해 Javascript 함수를 작성해야 했습니다.

이를 위해 obj2FormData() 함수를 작성했습니다.대괄호는 효과가 있는 것 같습니다.

function obj2FormData(obj, formData = new FormData()){

    this.formData = formData;

    this.createFormData = function(obj, subKeyStr = ''){
        for(let i in obj){
            let value          = obj[i];
            let subKeyStrTrans = subKeyStr ? subKeyStr + '[' + i + ']' : i;

            if(typeof(value) === 'string' || typeof(value) === 'number'){

                this.formData.append(subKeyStrTrans, value);

            } else if(typeof(value) === 'object'){

                this.createFormData(value, subKeyStrTrans);

            }
        }
    }

    this.createFormData(obj);

    return this.formData;
}

Ajax를 사용하여 데이터를 전송할 때 중첩된 개체를 FormData 개체로 변환합니다.

let formData = obj2FormData({
    name : 'Emrah',
    surname : 'Tuncel',
    birth: 1983,
    child : {
        name: 'Eylul',
        surname: 'Tuncel',
        toys: ['ball', 'baby']
    },
    color: ['red', 'yellow']
});

이제 Ajax로 변환한 FormData를 보내겠습니다.

const xhr = new XMLHttpRequest();
xhr.addEventListener('load', response => {
    //AJAX RESPONSE >>

    console.log(response);

    //AJAX RESPONSE //
});
xhr.open('POST','response.php');
xhr.send(formData);

PHP로 데이터를 화면에 눌렀더니 원하는 결과가 나왔습니다.방법이 POST인지 GET인지는 중요하지 않습니다.

대답.php

<pre><? print_r($_GET) ?></pre>
<pre><? print_r($_POST) ?></pre>

결과는 다음과 같습니다.

Array
(
    [name] => Emrah
    [surname] => Tuncel
    [birth] => 1983
    [child] => Array
        (
            [name] => Eylul
            [surname] => Tuncel
            [toys] => Array
                (
                    [0] => ball
                    [1] => baby
                )

        )

    [color] => Array
        (
            [0] => red
            [1] => yellow
        )

)

비즈니스에 도움이 되었으면 합니다.

FormData값이 자동으로 변환됩니다.stringBLOB를 사용해서 해보시면 됩니다.

아니면 그냥 스트링으로 넣을 수도 있고JSON.stringify(obj).

$.each(data, function(key, value){
    if (typeof(value) === 'object') {
        value = new Blob([JSON.stringify(value)], {type : 'application/json'});// or just JSON.stringify(value)
    }
    formData.append(key, value);
});

오브젝트를 FormData 인스턴스로 변환하는 편리한 JavaScript 함수는 npm 패키지로도 사용할 수 있으며 매우 사용하기 쉽습니다.

let data = {
    title: 'title',
    text: 'text',
    preview: {p_title:'p title', p_text: 'p text'}
};

var formData = objectToFormData(data);

이 작업은 다음과 같습니다.

사용하다.키와 서브키를 분리하다

let formData = new FormData();
let data = {
  title: 'title',
  text: 'text',
  preview: {p_title:'p title', p_text: 'p text'}
};

for(let key in data) {
  if(typeof(data[key]) === 'object') {
    for (let subKey in data[key]) {
      formData.append(`${key}.${subKey}`, data[key][subKey]);
    }
  }
  else {
    formData.append(key, data[key]);
  }
}

객체-폼 데이터를 사용해 보십시오.오브젝트를 FormData 인스턴스로 변환하는 편리한 JavaScript 함수입니다.

import { objectToFormData } from 'object-to-formdata';

const object = {
  /**
   * key-value mapping
   * values can be primitives or objects
   */
};

const options = {
  /**
   * include array indices in FormData keys
   * defaults to false
   */
  indices: false,

  /**
   * treat null values like undefined values and ignore them
   * defaults to false
   */
  nullsAsUndefineds: false,

  /**
   * convert true or false to 1 or 0 respectively
   * defaults to false
   */
  booleansAsIntegers: false,
};

const formData = objectToFormData(
  object,
  options, // optional
  existingFormData, // optional
  keyPrefix, // optional
);

console.log(formData);

서드파티 모듈을 사용할 필요가 없습니다.JSON.stringify()중첩된 개체가 있으면 이상적이지 않습니다.대신,Object.entries().

// If this is the object you want to convert to FormData...
const item = {
    description: 'First item',
    price: 13,
    photo: File
};

const formData = new FormData();

Object.entries(item).forEach(([key, value]) => {
    formData.append(key, value);
});

// At this point, you can then pass formData to your handler method

자세한 것은 이쪽Object.entries()이쪽 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

hashName[keyName] 사용

let formData = new FormData();
let data = {
  title: 'title',
  text: 'text',
  preview: {p_title:'p title', p_text: 'p text'}
};

for(let key in data) {
  if(typeof(data[key]) === 'object') {
    for (let subKey in data[key]) {
      formData.append('${key}[${subKey}]', data[key][subKey]);
    }
  }
  else {
    formData.append(key, data[key]);
  }
}

도움이 되었으면 합니다. 저는 더 간단한 방법으로 이 작업을 수행했고 모든 가설에 효과가 있다고 생각합니다. 테스트해 보십시오.

const parses = []

const fKey = key => ((function until(value, comp = value) {
    const result = value.replace(/\.([A-z0-9]*)(\.|$)/, '[$1]$2')

    return comp !== result ? until(result, value) : result
})(key))

function populateFormData(values, form = new FormData(), base = '') {
    Object.keys(values).forEach(key => {
        const value = values[key]

        if (typeof value == 'string' ||
            typeof value == 'number' ||
            typeof value == 'boolean') 
        {
            form.append(fKey(`${base}${key}`), value)
            parses.push({
                key: `${fKey(`${base}${key}`)}`,
                value
            })
        } 
        else if (typeof value == 'object') 
        {
            populateFormData(value, form, `${base}${key}.`)
        }
    })
    
    return form;
}

populateFormData({
    title: 'Lucas',
    text: 'Is good :)',
    preview: {
        p_title: 'I am a P title',
        p_text: 'I am a P text',
        test: {
            example: 2,
            my: {
                obj: [
                    'eba',
                    {
                        hyper: 'text'
                    },
                    123
                ],
                yes: true
            }
        }
    }
})

console.log(parses)

@Emrah Tuncel의 솔루션은 매우 양호합니다.아마도 조금 개선되었을 것입니다.

function object_to_form_data(data,formData,index = '') {

    for (const objKey in data) {

        const currentValue = data[objKey];
        const currentIndex = index ? `${index}[${objKey}]` : objKey;

        // Verify that currentValue is not an array, as arrays are also objects in js
        if (typeof currentValue === 'object' && !Array.isArray(currentValue)) {

            // If the currently iterated object is an empty object, we must not append it to the
            // formData, as that one will get appended as empty JSON object string too. In that case, as even null will
            // get parsed to "null" with formData, add a 'none' string as the value, and handle the
            // respective cases on the server side
            if (Object.keys(currentValue).length === 0) {
                formData.append(currentIndex,'none'); // You may change this to however you wanna handle empty objects
                continue;
            }

            object_to_form_data(currentValue,formData,currentIndex);

        } else {

            formData.append(currentIndex,currentValue);

        }

    }

}

주요 사항은 어레이가 Javascript에 "type of === 'object' 루프도 입력되므로 어레이를 고려하여 특별한 경우를 처리해야 한다는 것입니다.또한 중첩된 개체 내에 빈 개체 값이 있는 특수한 경우도 처리해야 합니다.적어도 사용 사례의 경우 서버 측의 객체 검증 및 삭제와 완전히 호환됩니다.

이 솔루션은 고객에게 좋은 솔루션이 될 수 있습니다.

function getFormData (obj = {}, formData = new FormData(), key = '') {
        if (!([Array, File, Object].includes(obj.constructor))) {
            return formData;
        }

        // Handle File recursive
        if (obj instanceof File) {
            formData.append(key, obj);
            return formData;
        }

        for (const prop in obj) {
            // Validate value type
            if (obj[prop] && !([String, Number, Boolean, Array, Object, File].includes(obj[prop].constructor))) {
                continue;
            }

            // Set deep index of prop
            const deepKey = key ? key + `[${prop}]` : prop;

            // Handle array
            if (Array.isArray(obj[prop])) {
                obj[prop].forEach((item, index) => {
                    getFormData(item, formData, `${deepKey}[${index}]`);
                })
                continue;
            }

            (typeof obj[prop] === 'object' && obj[prop] && obj[prop].constructor === Object)
                ? getFormData(obj[prop], formData, deepKey) // Handle object
                : formData.append(deepKey, [undefined, null].includes(obj[prop]) ? '' : obj[prop]) // Handle string, number, boolean
        }

        return formData;
    }

    const data = {
        string: 'abcd...',
        number: 1234,
        boolean: true,
        boolean2: false,
        object: {
            index: 1,
            value: 'value',
            boolean3: false,
        },
        array: [
            {
                index: 2,
                value: 'value 2'
            },
            {
                index: 3,
                value: 'value 3'
            },
            [
                {
                    index: 4,
                    value: 'value 2'
                },
                {
                    index: 5,
                    value: 'value 3',
                    boolean4: false,
                    null: null,
                    function: (x,y) => { return x + y; },
                },
                true,
                undefined,
                (x,y) => { return x + y; },
                new File(["woo"], 'woo.txt')
            ],
            false,
            new File(["foo"], 'file.txt')
        ],
    };

    const formData = getFormData(data);

    for (let pair of formData.entries()) {
        console.log(pair[0]+ ', ' + pair[1]);
    }

언급URL : https://stackoverflow.com/questions/52566331/formdata-append-nested-object

반응형