FormData के लिए सरणी संलग्न करना और AJAX के माध्यम से भेजना


109

मैं सरणी, पाठ फ़ील्ड और फ़ाइलों के साथ मल्टीपार्ट फ़ॉर्म सबमिट करने के लिए ajax का उपयोग कर रहा हूं।

मैं प्रत्येक VAR को मुख्य डेटा में जोड़ता हूं

var attachments = document.getElementById('files'); 
var data= new FormData();

for (i=0; i< attachments.files.length; i++){
    data.append('file', attachments.files[i]);
    console.log(attachments.files[i]);

    data.append ('headline', headline);
    data.append ('article', article);
    data.append ('arr', arr);
    data.append ('tag', tag);

तब मैं ajax फ़ंक्शन का उपयोग sql DB के अंदर स्टोर करने के लिए इसे PHP फ़ाइल में भेजने के लिए करता हूं।

$.ajax({    
    type: "post",
    url: 'php/submittionform.php',
    cache: false,
    processData: false,
    contentType: false,
    data: data,
    success: function(request) {$('#box').html(request); }
})

लेकिन PHP की तरफ, arrचर, जो एक सरणी है, एक स्ट्रिंग के रूप में दिखाई देता है।

जब मैं इसे फॉर्म डेटा के रूप में अजाक्स के साथ नहीं भेजता हूं, लेकिन साधारण $.POSTविकल्प का उपयोग करता हूं, तो मुझे इसे पीएचपी की ओर एक सरणी के रूप में मिलता है, लेकिन फिर मैं फ़ाइलों को भी नहीं भेज सकता।

कोई समाधान?

जवाबों:


92

आपके पास कई विकल्प हैं:

इसे JSON स्ट्रिंग में बदलें, फिर इसे PHP में पार्स करें (अनुशंसित)

जे एस

var json_arr = JSON.stringify(arr);

पीएचपी

$arr = json_decode($_POST['arr']);

या @ क्यूरियोस विधि का उपयोग करें

के माध्यम से एक सरणी भेजा जा रहा है FormData


अनुशंसित नहीं: PHP में deserialize के साथ डेटा को सीरियल करें

जे एस

// Use <#> or any other delimiter you want
var serial_arr = arr.join("<#>"); 

पीएचपी

$arr = explode("<#>", $_POST['arr']);

1
समस्या यह है कि सरणी में रिक्त स्थान और विराम चिह्नों के साथ वास्तविक पाठ की पंक्तियाँ हैं। मैं इसे गड़बड़ नहीं करना चाहता।
शुल्ट्ज

3
जब आप JSON के साथ एन्कोड और पार्स करते हैं, तो डेटा खो नहीं जाता है। इसे आजमाइए;)
रिचर्ड डे विट

यदि आप स्वत: मानचित्रण या कुछ इसी तरह के साथ asp.net का उपयोग कर रहे हैं, तो @Curious जवाब वही है जो आपको चाहिए।
मार्तीन Coll

1
@ रिचर्ड डी विट अगर आपके पास ऐसी फाइल या फॉर्मडाटा है तो आप उन्हें json.stringfy में खो देंगे
मोहसिन

मुझे स्ट्रिक्टेड बेहतर, सरल लगता है। जैसा कि आप [] का उपयोग कर सरणी के पास पारित करने के लिए कुछ प्रकार की पुनरावृत्ति करने की आवश्यकता है, लेकिन यह जानने के लिए अच्छा है कि उस तरह से किया जा सकता है।
चोपनट

260

आप FormDataइस तरह से एक सरणी भी भेज सकते हैं :

var formData = new FormData;
var arr = ['this', 'is', 'an', 'array'];
for (var i = 0; i < arr.length; i++) {
    formData.append('arr[]', arr[i]);
}

तो आप arr[]उसी तरह से लिख सकते हैं जैसे आप इसे साधारण HTML फॉर्म के साथ करते हैं। PHP के मामले में यह काम करना चाहिए।

आपको यह लेख उपयोगी लग सकता है: क्वेरी स्ट्रिंग के भीतर एक सरणी कैसे पास करें?


1
@Oleg लिखने के लिए की जरूरत क्या है arr[]में formData.append('arr[]', arr[i]);? क्यों arrसही नहीं है? मैंने दोनों की कोशिश की लेकिन केवल arr[]काम किया।
टोटरो

@Totoro क्योंकि arrआपके प्रत्येक लूप पुनरावृत्ति पर इस मान को फिर से परिभाषित करने के मामले में , और अंत में, अंतिम मूल्य पिछले सरणी तत्व के बराबर होगा, लेकिन पूरे सरणी नहीं
ओलेग

@ यदि मामला पुनर्परिभाषित हो रहा है तो क्या अलग है arr[], पुनर्वितरित क्यों नहीं arr[]किया जाता है? arr[]एक तार भी है। और जब दोनों न परीक्षण arrहै और न ही arr[]मेरे मामले में नए सिरे से परिभाषित किया गया था। मुझे एक ही कुंजी लेकिन अलग-अलग मूल्य के साथ फॉर्मडाटा में कई सरणी मिली। तो मैं arrमूल्य के साथ मिला 1और दूसरे arrमूल्य के साथ 2
तेतरो

@ टोटरो हाँ, तुम सही हो, मेरी गलती है। मेरा मानना ​​है कि यह अधिक सर्वर-विशिष्ट प्रश्न है। अलग-अलग भाषाएं क्वेरी स्ट्रिंग को अलग-अलग तरीके से पार्स कर सकती हैं। उदाहरण के लिए, PHP आपके द्वारा वर्णित की तरह व्यवहार करती है, लेकिन मैंने उदाहरण देखा (यदि मेमोरी जावा में कार्य करती है), जहां arrसरणियों के लिए भी काम किया। में इस विषय वहाँ इस सवाल का एक अधिक विस्तृत जवाब है
ओलेग

अगर किसी को वस्तुओं की एक सरणी पोस्ट करने की तलाश है, तो आप इस उत्तर को इस प्रकार बढ़ा सकते हैंfor (var i = 0; i < myArr; i++) { var myItemInArr = myArr[i]; for (var prop in myItemInArr) { fileData.append(`myArr[${i}][${prop}]`, myItemInArr[prop]); } }
edqwerty

7

यह एक पुराना सवाल है, लेकिन मैं इस समस्या में हाल ही में फ़ाइलों के साथ ऑब्जेक्ट पोस्ट करने के साथ भाग गया। मुझे एक वस्तु पोस्ट करने में सक्षम होने की आवश्यकता थी, जिसमें बच्चे के गुण थे जो कि वस्तुओं और सरणियों के रूप में भी थे।

नीचे दिया गया फ़ंक्शन किसी ऑब्जेक्ट के माध्यम से चलेगा और सही फॉर्मडाटा ऑब्जेक्ट बनाएगा।

// formData - instance of FormData object
// data - object to post
function getFormData(formData, data, previousKey) {
  if (data instanceof Object) {
    Object.keys(data).forEach(key => {
      const value = data[key];
      if (value instanceof Object && !Array.isArray(value)) {
        return this.getFormData(formData, value, key);
      }
      if (previousKey) {
        key = `${previousKey}[${key}]`;
      }
      if (Array.isArray(value)) {
        value.forEach(val => {
          formData.append(`${key}[]`, val);
        });
      } else {
        formData.append(key, value);
      }
    });
  }
}

यह निम्नलिखित json को रूपांतरित करेगा -

{
  name: 'starwars',
  year: 1977,
  characters: {
    good: ['luke', 'leia'],
    bad: ['vader'],
  },
}

निम्नलिखित प्रपत्र में

 name, starwars
 year, 1977
 characters[good][], luke
 characters[good][], leia
 characters[bad][], vader

यह मेरे लिए उपयोगी था, बस एपेंड के अंदर मूल्य पर स्ट्रिंग (मूल्य) लागू करना था (अन्यथा यह सच / गलत के लिए विफल रहता है)। इसके अलावा यह (value !== null) && formData.append(key, value)सिर्फ इसके बजाय होना चाहिए formData.append(key, value)अन्यथा यह अशक्त मूल्यों पर विफल रहता है
अलेक्जेंडर

7

टाइपस्क्रिप्ट संस्करण:

export class Utility {      
    public static convertModelToFormData(model: any, form: FormData = null, namespace = ''): FormData {
        let formData = form || new FormData();
        let formKey;

        for (let propertyName in model) {
            if (!model.hasOwnProperty(propertyName) || !model[propertyName]) continue;
            let formKey = namespace ? `${namespace}[${propertyName}]` : propertyName;
            if (model[propertyName] instanceof Date)
                formData.append(formKey, model[propertyName].toISOString());
            else if (model[propertyName] instanceof Array) {
                model[propertyName].forEach((element, index) => {
                    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;
    }
}

का उपयोग करते हुए:

let formData = Utility.convertModelToFormData(model);

महान काम, सुपर उपयोगी: डी
कॉस्मो चेलिनी

3

FormData में सभी प्रकार के इनपुट जोड़ें

const formData = new FormData();
for (let key in form) {
    Array.isArray(form[key])
        ? form[key].forEach(value => formData.append(key + '[]', value))
        : formData.append(key, form[key]) ;
}

2

यदि आपके पास ऑब्जेक्ट्स और एरेज़ हैं, तो फॉर्मडेटा ऑब्जेक्ट को पॉप्युलेट करने का सबसे अच्छा तरीका रिकर्सन का उपयोग करना है।

function createFormData(formData, data, key) {
    if ( ( typeof data === 'object' && data !== null ) || Array.isArray(data) ) {
        for ( let i in data ) {
            if ( ( typeof data[i] === 'object' && data[i] !== null ) || Array.isArray(data[i]) ) {
                createFormData(formData, data[i], key + '[' + i + ']');
            } else {
                formData.append(key + '[' + i + ']', data[i]);
            }
        }
    } else {
        formData.append(key, data);
    }
}

1

सरल मूल्यों की किरणों वाले मॉडल के लिए अगला संस्करण मान्य है:

function convertModelToFormData(val, formData = new FormData(), namespace = '') {
    if((typeof val !== 'undefined') && (val !== null)) {
        if(val instanceof Date) {
            formData.append(namespace, val.toISOString());
        } else if(val instanceof Array) {
            for(let element of val) {
                convertModelToFormData(element, formData, namespace + '[]');
            }
        } else if(typeof val === 'object' && !(val instanceof File)) {
            for (let propertyName in val) {
                if(val.hasOwnProperty(propertyName)) {
                    convertModelToFormData(val[propertyName], formData, namespace ? namespace + '[' + propertyName + ']' : propertyName);
                }
            }
        } else {
            formData.append(namespace, val.toString());
        }
    }
    return formData;
}

1

@YackY उत्तर के आधार पर संक्षिप्त पुनरावर्तन संस्करण:

function createFormData(formData, key, data) {
    if (data === Object(data) || Array.isArray(data)) {
        for (var i in data) {
            createFormData(formData, key + '[' + i + ']', data[i]);
        }
    } else {
        formData.append(key, data);
    }
}

उपयोग उदाहरण:

var data = {a: '1', b: 2, c: {d: '3'}};
var formData = new FormData();
createFormData(formData, 'data', data);

भेजा गया डेटा:

data[a]=1&
data[b]=2&
data[c][d]=3
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.