175 votes

ajouter un tableau à FormData et l'envoyer via AJAX

J'utilise l'ajax pour soumettre un formulaire multipartite avec des tableaux, des champs de texte et des fichiers.

J'ajoute chaque VAR aux données principales comme suit

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);

puis j'utilise la fonction ajax pour l'envoyer à un fichier PHP pour le stocker dans la base de données sql.

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

Mais du côté de PHP, le arr qui est un tableau apparaît comme une chaîne de caractères.

Lorsque je ne l'envoie pas avec ajax en tant que données de formulaire mais que j'utilise le simple $.POST J'obtiens bien un tableau du côté de PHP, mais je ne peux pas envoyer les fichiers non plus.

des solutions ?

371voto

Oleg Points 13418

Vous pouvez également envoyer un tableau via FormData de cette façon :

var formData = new FormData;
var arr = ['this', 'is', 'an', 'array'];

for (var i = 0; i < arr.length; i++) {
  formData.append('arr[]', arr[i]);
}

console.log(...formData);

Vous pouvez donc écrire arr[] de la même manière que vous le faites avec un simple formulaire HTML. Dans le cas de PHP, cela devrait fonctionner.

Vous trouverez peut-être cet article utile : Comment passer un tableau dans une chaîne de requête ?

149voto

GeenHenk Points 1494

Vous avez plusieurs possibilités :

Convertissez-le en une chaîne JSON, puis analysez-le en PHP (recommandé).

JS

var json_arr = JSON.stringify(arr);

PHP

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

Ou utilisez La méthode de @Curios

Envoi d'un tableau par FormData .


Non recommandé : Sérialisez les données avec, puis désérialisez en PHP.

JS

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

PHP

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

14voto

Mohammad Points 2448

Version dactylographiée :

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;
    }
}

Utilisation :

let formData = Utility.convertModelToFormData(model);

8voto

VtoCorleone Points 1673

Il s'agit d'une vieille question, mais j'ai rencontré ce problème avec l'affichage d'objets avec des fichiers récemment. Je devais être en mesure d'afficher un objet, avec des propriétés enfant qui étaient des objets et des tableaux également.

La fonction ci-dessous va parcourir un objet et créer l'objet formData correct.

// 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);
      }
    });
  }
}

Cela convertira le json suivant -

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

dans le FormData suivant

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

5voto

HamidNE Points 87

Ajouter toutes les entrées de type à 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]) ;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X