แปลง JS Object เป็นข้อมูลในรูปแบบ


130

ฉันจะแปลง JS Object เป็นได้FormDataอย่างไร

เหตุผลที่ฉันต้องการทำสิ่งนี้คือฉันมีวัตถุที่ฉันสร้างจากค่าฟิลด์ฟอร์ม ~ 100

var item = {
   description: 'Some Item',
   price : '0.00',
   srate : '0.00',
   color : 'red',
   ...
   ...
}

ตอนนี้ผมขอให้เพิ่มฟังก์ชั่นการอัปโหลดไฟล์ไปยังรูปแบบของฉันซึ่งของหลักสูตรเป็นไปไม่ได้ผ่าน JSON FormDataและดังนั้นผมกำลังวางแผนในการที่จะย้ายไป มีวิธีใดบ้างที่ฉันสามารถแปลงวัตถุ JS ของฉันเป็นFormData?


คุณสามารถแบ่งปันงาน / ความคืบหน้าของคุณได้หรือไม่?
Ritikesh

JSON.stringify () เป็นอย่างไร
Sunny Sharma

1
@Sunny - นั่นจะสร้างข้อความ JSON ในสตริง นั่นไม่ใช่FormDataวัตถุ
Quentin

ได้คุณสามารถต่อท้ายวัตถุ formData ได้
adeneo

คุณช่วยแสดงให้เราเห็นว่า FormData หมายถึงอะไร? รูปแบบเฉพาะใด ๆ
Sunny Sharma

คำตอบ:


156

หากคุณมีออบเจ็กต์คุณสามารถสร้างออบเจ็กต์ FormData และต่อท้ายชื่อและค่าจากอ็อบเจ็กต์นั้นไปยัง formData

คุณไม่ได้โพสต์โค้ดใด ๆ ดังนั้นจึงเป็นตัวอย่างทั่วไป

var form_data = new FormData();

for ( var key in item ) {
    form_data.append(key, item[key]);
}

$.ajax({
    url         : 'http://example.com/upload.php',
    data        : form_data,
    processData : false,
    contentType : false,
    type: 'POST'
}).done(function(data){
    // do stuff
});

มีตัวอย่างเพิ่มเติมในเอกสารของMDN


4
@Lior - itemเป็นวัตถุปกติที่สร้างขึ้นโดย OP ดังนั้นจึงไม่ควรมีคุณสมบัติใด ๆ ที่ไม่ใช่ของตัวเองเว้นแต่จะมีคนทำผิดพลาดในการสร้างต้นแบบบางสิ่งลงบนตัวสร้างวัตถุซึ่งในกรณีนี้คุณจะตกอยู่ในโลกแห่งปัญหา และไม่ใช่สิ่งที่เราควรต้องป้องกัน
adeneo

2
@Lior - เป็นเพียงการเพิ่มคู่คีย์ / ค่าลงใน FormData การเพิ่มคุณสมบัติต้นแบบจะไม่ทำลายอะไรเลยและการใช้Object.keysไม่ใช่คำตอบเนื่องจากคุณไม่ควรรับคีย์เป็นอาร์เรย์จากนั้นทำซ้ำบนคีย์เพื่อรับ ค่าคุณควรใช้for..inลูป
adeneo

2
แน่นอนว่าคุณจะไม่รู้ว่าเซิร์ฟเวอร์กำลังคาดหวังอะไร ... สำหรับ ... ใน JS นั้นเป็นความน่าจะเป็นวิธีการแก้ปัญหาไม่จำเป็นต้องเป็น Object.keys () มันอาจเป็น hasOwnProperty () แต่ อย่างน้อยก็ต้องมีคำเตือน
Lior

3
@Lior - หากเซิร์ฟเวอร์ของคุณหยุดทำงานเมื่อได้รับคู่คีย์ / ค่าเพิ่มอีกหนึ่งคู่ในคำขอ POST แสดงว่าคุณทำผิด ฉันคิดว่าคำตอบนั้นดีและฉันจะไม่เปลี่ยนเป็นใช้Object.keysหรือhasOwnProperty()ตามที่มีการโพสต์วัตถุในคำถามและไม่ควรต้องการสิ่งเหล่านั้น เหตุผลที่บางครั้งคุณเห็นว่าhasOwnPropertyใช้ในปลั๊กอิน ฯลฯ เป็นเพราะคุณไม่มีทางรู้ว่าบางคนอาจทำอะไรกับตัวObjectสร้าง แต่ส่วนใหญ่แล้วคนส่วนใหญ่ไม่ควรต้องทดสอบคุณสมบัติที่สืบทอดมาบนวัตถุที่พวกเขาสร้างขึ้นนั่นเป็นสัญญาณว่า คุณอาจทำอะไรผิดพลาด
adeneo

5
@Lior คุณตั้งใจจะสร้างเครื่องบินจากฟางต่อไปโดยหวังว่าจะดึงดูดเครื่องบินจริงมากขึ้นที่จะทิ้งอาหารจากท้องฟ้าหรือไม่? สิ่งสำคัญคือต้องทำความเข้าใจว่าเหตุใดจึงใช้การตรวจสอบ hasOwnProperty เพียงแค่บอกว่าสิ่งต่างๆถือเป็น "แนวทางปฏิบัติที่ดีที่สุด" เพราะคุณอ่านหนังสือของใครบางคน (เดาว่า Crockford) ไม่ได้ช่วยให้คุณเข้าใจได้ไกลนักการพยายามให้ความรู้แก่เพื่อนสมาชิกมากกว่า 100 ครั้ง ชื่อเสียงและจำนวนคำตอบ 100 เท่าก็ไม่ได้ช่วยอะไรมากนักเช่นกัน นอกจากนี้ชื่อหนึ่ง lib บุคคลที่สามใหม่ที่มีการเปลี่ยนแปลงต้นแบบ? โพสต์นั้นมาจากเวลาอื่น ...
Benjamin Gruenbaum

85

ด้วย ES6 และวิธีการเขียนโปรแกรมที่ใช้งานได้มากขึ้นคำตอบของ @ adeneo อาจมีลักษณะดังนี้:

function getFormData(object) {
    const formData = new FormData();
    Object.keys(object).forEach(key => formData.append(key, object[key]));
    return formData;
}

และอีกทางเลือกหนึ่งโดยใช้.reduce()และฟังก์ชันลูกศร:

getFormData = object => Object.keys(object).reduce((formData, key) => {
    formData.append(key, object[key]);
    return formData;
}, new FormData());

45

ฟังก์ชันนี้จะเพิ่มข้อมูลทั้งหมดจากออบเจ็กต์ไปยัง FormData

รุ่น ES6 จาก @ developer033:

function buildFormData(formData, data, parentKey) {
  if (data && typeof data === 'object' && !(data instanceof Date) && !(data instanceof File)) {
    Object.keys(data).forEach(key => {
      buildFormData(formData, data[key], parentKey ? `${parentKey}[${key}]` : key);
    });
  } else {
    const value = data == null ? '' : data;

    formData.append(parentKey, value);
  }
}

function jsonToFormData(data) {
  const formData = new FormData();

  buildFormData(formData, data);

  return formData;
}

const my_data = {
  num: 1,
  falseBool: false,
  trueBool: true,
  empty: '',
  und: undefined,
  nullable: null,
  date: new Date(),
  name: 'str',
  another_object: {
    name: 'my_name',
    value: 'whatever'
  },
  array: [
    {
      key1: {
        name: 'key1'
      }
    }
  ]
};

jsonToFormData(my_data)

jQuery เวอร์ชัน:

function appendFormdata(FormData, data, name){
    name = name || '';
    if (typeof data === 'object'){
        $.each(data, function(index, value){
            if (name == ''){
                appendFormdata(FormData, value, index);
            } else {
                appendFormdata(FormData, value, name + '['+index+']');
            }
        })
    } else {
        FormData.append(name, data);
    }
}


var formData = new FormData(),
    your_object = {
        name: 'test object',
        another_object: {
            name: 'and other objects',
            value: 'whatever'
        }
    };
appendFormdata(formData, your_object);

Nice Keep it up
Vivek Doshi

ใช้งานได้ดีมาก! ขอบคุณ! ฉันต้องเพิ่ม&& !(data instanceof Blob)ในกรณีของฉันเพื่ออัปโหลดภาพของฉัน
Clément Baconnier

ทำงานได้ดีสำหรับฉันฉันเพิ่มถ้า (typeof data === 'object' && data! == null) {เพราะมันถูกโยนข้อยกเว้นถ้าค่าเป็นโมฆะ
al000y

สำหรับเวอร์ชัน ES6 ฉันได้เพิ่ม&& !(Array.isArray(data) && !data.length)เงื่อนไข "if" มิฉะนั้นอาร์เรย์ว่างจะถูกลบออก
Mtxz

นี่คืออัจฉริยะ แก้ไขปัญหาของฉันได้อย่างสวยงาม
dearsina

15

คำตอบอื่น ๆ ไม่สมบูรณ์สำหรับฉัน ฉันเริ่มต้นจากคำตอบของ @Vladimir Novopashin และแก้ไข นี่คือสิ่งที่ฉันต้องการและข้อบกพร่องที่ฉันพบ:

  • รองรับไฟล์
  • รองรับอาร์เรย์
  • จุดบกพร่อง: ต้องเพิ่มไฟล์ภายในวัตถุที่ซับซ้อน.propแทน[prop]ไฟล์. ตัวอย่างเช่นformData.append('photos[0][file]', file)ไม่ทำงานบน Google Chrome ในขณะที่ formData.append('photos[0].file', file)ทำงาน
  • ละเว้นคุณสมบัติบางอย่างในวัตถุของฉัน

รหัสต่อไปนี้ควรใช้ได้กับ IE11 และเบราว์เซอร์ที่เขียวชอุ่มตลอดปี

function objectToFormData(obj, rootName, ignoreList) {
    var formData = new FormData();

    function appendFormData(data, root) {
        if (!ignore(root)) {
            root = root || '';
            if (data instanceof File) {
                formData.append(root, data);
            } else if (Array.isArray(data)) {
                for (var i = 0; i < data.length; i++) {
                    appendFormData(data[i], root + '[' + i + ']');
                }
            } else if (typeof data === 'object' && data) {
                for (var key in data) {
                    if (data.hasOwnProperty(key)) {
                        if (root === '') {
                            appendFormData(data[key], key);
                        } else {
                            appendFormData(data[key], root + '.' + key);
                        }
                    }
                }
            } else {
                if (data !== null && typeof data !== 'undefined') {
                    formData.append(root, data);
                }
            }
        }
    }

    function ignore(root){
        return Array.isArray(ignoreList)
            && ignoreList.some(function(x) { return x === root; });
    }

    appendFormData(obj, rootName);

    return formData;
}

2
คำตอบเดียวที่รองรับอาร์เรย์วัตถุและไฟล์
sotn

สวัสดีทำไมคุณเพิ่มไฟล์ลงในรูท? เป็นไปได้หรือไม่ที่จะเพิ่มให้เด็กด้วย?
Cedric Arnould

@CedricArnould มันอาจจะเป็นความเข้าใจผิด แต่เมธอดนั้นเป็นแบบวนซ้ำดังนั้นแม้ว่ามันจะถูกเขียนขึ้นformData.append(root, data)แต่ก็ไม่ได้หมายความว่ามันจะถูกเพิ่มเข้าไปในรูท
Gudradain

ฉันเข้าใจคำตอบของคุณแปลกมากเมื่อฉันได้รับผลลัพธ์ในเซิร์ฟเวอร์ฉันมีคอลเล็กชันไฟล์และข้อมูลที่เป็นเอกลักษณ์ แต่ฉันเห็นในไฟล์ชื่อให้ข้อมูลที่เด็กเชื่อมต่อ บางทีปัญหาอาจมาจาก. Net Core และวิธีจัดการไฟล์อัปโหลด ขอบคุณสำหรับคำตอบ.
Cedric Arnould

ฉันกำลังพยายามใช้สิ่งนี้ แต่ไม่มีตัวอย่างการใช้งาน รูปแบบที่คาดไว้ของพารามิเตอร์ละเว้นจะมีประโยชน์มาก
jpro

9

ลองใช้ฟังก์ชัน JSON.stringify ดังต่อไปนี้

var postData = JSON.stringify(item);
var formData = new FormData();
formData.append("postData",postData );

1
นี่เป็นวิธีที่ดีที่สุดในการบรรลุเป้าหมายนี้
Rob

มันให้ต่อท้าย json หลังจากดีบั๊กข้อผิดพลาดหลายครั้ง
Snow Bases

7

ฉันมีสถานการณ์สมมติที่ JSON ที่ซ้อนกันต้องถูกทำให้เป็นอนุกรมในรูปแบบเชิงเส้นในขณะที่สร้างข้อมูลแบบฟอร์มเนื่องจากนี่คือวิธีที่เซิร์ฟเวอร์คาดหวังค่า ดังนั้นฉันจึงเขียนฟังก์ชันเรียกซ้ำขนาดเล็กซึ่งแปล JSON ซึ่งเป็นดังนี้:

{
   "orderPrice":"11",
   "cardNumber":"************1234",
   "id":"8796191359018",
   "accountHolderName":"Raj Pawan",
   "expiryMonth":"02",
   "expiryYear":"2019",
   "issueNumber":null,
   "billingAddress":{
      "city":"Wonderland",
      "code":"8796682911767",
      "firstname":"Raj Pawan",
      "lastname":"Gumdal",
      "line1":"Addr Line 1",
      "line2":null,
      "state":"US-AS",
      "region":{
         "isocode":"US-AS"
      },
      "zip":"76767-6776"
   }
}

ในสิ่งนี้:

{
   "orderPrice":"11",
   "cardNumber":"************1234",
   "id":"8796191359018",
   "accountHolderName":"Raj Pawan",
   "expiryMonth":"02",
   "expiryYear":"2019",
   "issueNumber":null,
   "billingAddress.city":"Wonderland",
   "billingAddress.code":"8796682911767",
   "billingAddress.firstname":"Raj Pawan",
   "billingAddress.lastname":"Gumdal",
   "billingAddress.line1":"Addr Line 1",
   "billingAddress.line2":null,
   "billingAddress.state":"US-AS",
   "billingAddress.region.isocode":"US-AS",
   "billingAddress.zip":"76767-6776"
}

เซิร์ฟเวอร์จะยอมรับข้อมูลฟอร์มซึ่งอยู่ในรูปแบบที่แปลงนี้

นี่คือฟังก์ชั่น:

function jsonToFormData (inJSON, inTestJSON, inFormData, parentKey) {
    // http://stackoverflow.com/a/22783314/260665
    // Raj: Converts any nested JSON to formData.
    var form_data = inFormData || new FormData();
    var testJSON = inTestJSON || {};
    for ( var key in inJSON ) {
        // 1. If it is a recursion, then key has to be constructed like "parent.child" where parent JSON contains a child JSON
        // 2. Perform append data only if the value for key is not a JSON, recurse otherwise!
        var constructedKey = key;
        if (parentKey) {
            constructedKey = parentKey + "." + key;
        }

        var value = inJSON[key];
        if (value && value.constructor === {}.constructor) {
            // This is a JSON, we now need to recurse!
            jsonToFormData (value, testJSON, form_data, constructedKey);
        } else {
            form_data.append(constructedKey, inJSON[key]);
            testJSON[constructedKey] = inJSON[key];
        }
    }
    return form_data;
}

ภาวนา:

        var testJSON = {};
        var form_data = jsonToFormData (jsonForPost, testJSON);

ฉันใช้ testJSON เพียงเพื่อดูผลลัพธ์ที่แปลงแล้วเนื่องจากฉันไม่สามารถแยกเนื้อหาของ form_data ได้ AJAX โพสต์โทร:

        $.ajax({
            type: "POST",
            url: somePostURL,
            data: form_data,
            processData : false,
            contentType : false,
            success: function (data) {
            },
            error: function (e) {
            }
        });

สวัสดี Raj แล้วอาร์เรย์ล่ะ สมมติว่าคุณมีที่อยู่สำหรับการเรียกเก็บเงินมากกว่า 1 แห่ง คุณจะแก้ไขอย่างไร
แซม

1
ฉันพบคำตอบแล้ว! โพสต์ของคุณมีประโยชน์มาก ขอบคุณ!
แซม

3

ขออภัยสำหรับคำตอบที่ล่าช้า แต่ฉันประสบปัญหานี้เนื่องจาก Angular 2 ไม่รองรับการอัปโหลดไฟล์ในขณะนี้ ดังนั้นวิธีที่จะทำมันถูกส่งด้วยXMLHttpRequest FormDataฉันจึงสร้างฟังก์ชันขึ้นมา ฉันใช้typescript ในการแปลงเป็นJavascriptเพียงแค่ลบการประกาศประเภทข้อมูล

/**
     * Transforms the json data into form data.
     *
     * Example:
     *
     * Input:
     * 
     * fd = new FormData();
     * dob = {
     *  name: 'phone',
     *  photos: ['myphoto.jpg', 'myotherphoto.png'],
     *  price: '615.99',
     *  color: {
     *      front: 'red',
     *      back: 'blue'
     *  },
     *  buttons: ['power', 'volup', 'voldown'],
     *  cameras: [{
     *      name: 'front',
     *      res: '5Mpx'
     *  },{
     *      name: 'back',
     *      res: '10Mpx'
     *  }]
     * };
     * Say we want to replace 'myotherphoto.png'. We'll have this 'fob'.
     * fob = {
     *  photos: [null, <File object>]
     * };
     * Say we want to wrap the object (Rails way):
     * p = 'product';
     *
     * Output:
     *
     * 'fd' object updated. Now it will have these key-values "<key>, <value>":
     *
     * product[name], phone
     * product[photos][], myphoto.jpg
     * product[photos][], <File object>
     * product[color][front], red
     * product[color][back], blue
     * product[buttons][], power
     * product[buttons][], volup
     * product[buttons][], voldown
     * product[cameras][][name], front
     * product[cameras][][res], 5Mpx
     * product[cameras][][name], back
     * product[cameras][][res], 10Mpx
     * 
     * @param {FormData}  fd  FormData object where items will be appended to.
     * @param {Object}    dob Data object where items will be read from.
     * @param {Object =   null} fob File object where items will override dob's.
     * @param {string =   ''} p Prefix. Useful for wrapping objects and necessary for internal use (as this is a recursive method).
     */
    append(fd: FormData, dob: Object, fob: Object = null, p: string = ''){
        let apnd = this.append;

        function isObj(dob, fob, p){
            if(typeof dob == "object"){
                if(!!dob && dob.constructor === Array){
                    p += '[]';
                    for(let i = 0; i < dob.length; i++){
                        let aux_fob = !!fob ? fob[i] : fob;
                        isObj(dob[i], aux_fob, p);
                    }
                } else {
                    apnd(fd, dob, fob, p);
                }
            } else {
                let value = !!fob ? fob : dob;
                fd.append(p, value);
            }
        }

        for(let prop in dob){
            let aux_p = p == '' ? prop : `${p}[${prop}]`;
            let aux_fob = !!fob ? fob[prop] : fob;
            isObj(dob[prop], aux_fob, aux_p);
        }
    }

คุณต้องรวมดัชนีอาร์เรย์แทน a []สำหรับคุณสมบัติวัตถุภายในอาร์เรย์ตัวเลขเพื่อให้คงสภาพเดิม
Vicary

1

เวอร์ชัน TypeScript:

static convertModelToFormData(model: any, form: FormData = null, namespace = ''): FormData {
    let formData = form || new FormData();
    for (let propertyName in model) {
      if (!model.hasOwnProperty(propertyName) || model[propertyName] == undefined) continue;
      let formKey = namespace ? `${namespace}[${propertyName}]` : propertyName;
      if (model[propertyName] instanceof Date) {        
        formData.append(formKey, this.dateTimeToString(model[propertyName]));
      }
      else if (model[propertyName] instanceof Array) {
        model[propertyName].forEach((element, index) => {
          if (typeof element != 'object')
            formData.append(`${formKey}[]`, element);
          else {
            const tempFormKey = `${formKey}[${index}]`;
            this.convertModelToFormData(element, formData, tempFormKey);
          }
        });
      }
      else if (typeof model[propertyName] === 'object' && !(model[propertyName] instanceof File)) {        
        this.convertModelToFormData(model[propertyName], formData, formKey);
      }
      else {        
        formData.append(formKey, model[propertyName].toString());
      }
    }
    return formData;
  }

https://gist.github.com/Mds92/091828ea857cc556db2ca0f991fee9f6


1
ก่อนอื่นnamespaceคือคีย์เวิร์ดที่สงวนไว้ในTypeScript( typescriptlang.org/docs/handbook/namespaces.htmlและgithub.com/Microsoft/TypeScript/issues/… ) นอกจากนี้ดูเหมือนว่าคุณจะลืมที่จะจัดการFileตั้งแต่elseพินัยกรรมสุดท้ายappend "[object File]"จนถึงformData.
Jyrkka

1

คุณสามารถติดตั้งqs:

npm i qs

เพียงแค่นำเข้า:

import qs from 'qs'

ส่งวัตถุไปที่qs.stringify():

var item = {
   description: 'Some Item',
   price : '0.00',
   srate : '0.00',
   color : 'red',
   ...
   ...
}

qs.stringify(item)

1

ซ้ำ

const toFormData = (f => f(f))(h => f => f(x => h(h)(f)(x)))(f => fd => pk => d => {
  if (d instanceof Object) {
    Object.keys(d).forEach(k => {
      const v = d[k]
      if (pk) k = `${pk}[${k}]`
      if (v instanceof Object && !(v instanceof Date) && !(v instanceof File)) {
        return f(fd)(k)(v)
      } else {
        fd.append(k, v)
      }
    })
  }
  return fd
})(new FormData())()

let data = {
  name: 'John',
  age: 30,
  colors: ['red', 'green', 'blue'],
  children: [
    { name: 'Max', age: 3 },
    { name: 'Madonna', age: 10 }
  ]
}
console.log('data', data)
document.getElementById("data").insertAdjacentHTML('beforeend', JSON.stringify(data))

let formData = toFormData(data)

for (let key of formData.keys()) {
  console.log(key, formData.getAll(key).join(','))
  document.getElementById("item").insertAdjacentHTML('beforeend', `<li>${key} = ${formData.getAll(key).join(',')}</li>`)
}
<p id="data"></p>
<ul id="item"></ul>


IMHO ตอบที่ดีที่สุด
หลิง

0

วิธีนี้แปลงวัตถุ JS เป็น FormData:

function convertToFormData(params) {
    return Object.entries(params)
        .reduce((acc, [key, value]) => {
            if (Array.isArray(value)) {
                value.forEach((v, k) => acc.append(`${key}[${k}]`, value));
            } else if (typeof value === 'object' && !(value instanceof File) && !(value instanceof Date)) {
                Object.entries(value).forEach((v, k) => acc.append(`${key}[${k}]`, value));
            } else {
                acc.append(key, value);
            }

            return acc;
        }, new FormData());
}


เพียงแค่แก้ไขการทำซ้ำรายการวัตถุที่ซ้อนกัน call: Object.entries(value).forEach((v, k) => acc.append(`${key}[${v[0]}]`, v[1]));
heber gentilin

0

ในกรณีของฉันวัตถุของฉันยังมีคุณสมบัติซึ่งเป็นอาร์เรย์ของไฟล์ เนื่องจากเป็นไบนารีจึงควรได้รับการจัดการที่แตกต่างกันดัชนีไม่จำเป็นต้องเป็นส่วนหนึ่งของคีย์ ดังนั้นฉันจึงแก้ไขคำตอบของ @Vladimir Novopashin และ @ developer033:

export function convertToFormData(data, formData, parentKey) {
  if(data === null || data === undefined) return null;

  formData = formData || new FormData();

  if (typeof data === 'object' && !(data instanceof Date) && !(data instanceof File)) {
    Object.keys(data).forEach(key => 
      convertToFormData(data[key], formData, (!parentKey ? key : (data[key] instanceof File ? parentKey : `${parentKey}[${key}]`)))
    );
  } else {
    formData.append(parentKey, data);
  }

  return formData;
}

0

ฉันใช้สิ่งนี้สำหรับโพสต์ข้อมูลวัตถุของฉันเป็นข้อมูลแบบฟอร์ม

const encodeData = require('querystring');

const object = {type: 'Authorization', username: 'test', password: '123456'};

console.log(object);
console.log(encodeData.stringify(object));

0

บางทีคุณอาจกำลังมองหาสิ่งนี้รหัสที่รับวัตถุจาวาสคริปต์ของคุณสร้างวัตถุFormDataจากนั้นโพสต์ไปยังเซิร์ฟเวอร์ของคุณโดยใช้Fetch APIใหม่:

    let myJsObj = {'someIndex': 'a value'};

    let datos = new FormData();
    for (let i in myJsObj){
        datos.append( i, myJsObj[i] );
    }

    fetch('your.php', {
        method: 'POST',
        body: datos
    }).then(response => response.json())
        .then(objson => {
            console.log('Success:', objson);
        })
        .catch((error) => {
            console.error('Error:', error);
        });

0

ผมอ้างอิงจากคำตอบของ Gudradain ฉันแก้ไขเล็กน้อยในรูปแบบ typescript

class UtilityService {
    private appendFormData(formData, data, rootName) {

        let root = rootName || '';
        if (data instanceof File) {
            formData.append(root, data);
        } else if (Array.isArray(data)) {
            for (var i = 0; i < data.length; i++) {
                this.appendFormData(formData, data[i], root + '[' + i + ']');
            }
        } else if (typeof data === 'object' && data) {
            for (var key in data) {
                if (data.hasOwnProperty(key)) {
                    if (root === '') {
                        this.appendFormData(formData, data[key], key);
                    } else {
                        this.appendFormData(formData, data[key], root + '.' + key);
                    }
                }
            }
        } else {
            if (data !== null && typeof data !== 'undefined') {
                formData.append(root, data);
            }
        }
    }

    getFormDataFromObj(data) {
        var formData = new FormData();

        this.appendFormData(formData, data, '');

        return formData;
    }
}

export let UtilityMan = new UtilityService();

0

ฉันอาจจะไปปาร์ตี้ช้าไปหน่อย แต่นี่คือสิ่งที่ฉันสร้างขึ้นเพื่อแปลงวัตถุเอกพจน์เป็น FormData

function formData(formData, filesIgnore = []) {
  let data = new FormData();

  let files = filesIgnore;

  Object.entries(formData).forEach(([key, value]) => {
    if (typeof value === 'object' && !files.includes(key)) {
      data.append(key, JSON.stringify(value) || null);
    } else if (files.includes(key)) {
      data.append(key, value[0] || null);
    } else {
      data.append(key, value || null);
    }
  })

  return data;
}

มันทำงานอย่างไร? มันจะแปลงและกลับคุณสมบัติทั้งหมดคาดว่าวัตถุไฟล์ที่คุณตั้งไว้ในรายชื่อ (อาร์กิวเมนต์ 2. ถ้าใครสามารถบอกฉันวิธีที่ดีกว่านี้ในการกำหนดที่จะช่วยให้!) เป็นสตริง JSON JSON.stringifyโดยใช้ จากนั้นบนเซิร์ฟเวอร์ของคุณคุณจะต้องแปลงกลับเป็นออบเจ็กต์ JSON

ตัวอย่าง:

let form = {
  first_name: 'John',
  last_name: 'Doe',
  details: {
    phone_number: 1234 5678 910,
    address: '123 Some Street',
  },
  profile_picture: [object FileList] // set by your form file input. Currently only support 1 file per property.
}

function submit() {
  let data = formData(form, ['profile_picture']);

  axios.post('/url', data).then(res => {
    console.log('object uploaded');
  })
}

ฉันยังใหม่กับคำขอ Http และ JavaScript ดังนั้นข้อเสนอแนะใด ๆ จะได้รับการชื่นชมอย่างมาก!


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.