добавление массива в FormData и отправка через AJAX



Я использую 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, чтобы отправить его в PHP-файл для хранения внутри SQL DB.



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


но на стороне PHP,arr переменная, представляющая собой массив, отображается в виде строки.



когда я не отправляю его с ajax в качестве данных формы, но использовать простой $.POST вариант я получаю его как массив на стороне PHP, но тогда я не могу отправить файлы, а также.



какие решения?

846   5  

5 ответов:

у вас есть несколько вариантов:

преобразовать его в строку JSON, а затем проанализировать его в PHP (рекомендуется)

JS

var json_arr = JSON.stringify(arr);

PHP

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

или использовать @ Curios метод

отправка массива через FormData.


Не рекомендуется: сериализовать данные с помощью, а затем десериализовать в PHP

JS

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

PHP

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

вы также можете отправить массив через 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 это должно работать.

вы можете найти эту статью полезной: как передать массив в строке запроса?

Это старый вопрос, но я столкнулся с проблемой с размещением недавно вместе с файлами. Мне нужно было иметь возможность публиковать объект с дочерними свойствами, которые также были объектами и массивами.

функция ниже будет проходить через объект и создать правильный объект formData.

// 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'],
  },
}

в следующий FormData

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

версия Typescript:

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

следующая версия действительна для модели, содержащей Арай простых значений:

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

Comments

    Ничего не найдено.