array - formdata() javascript
Anexar matriz a FormData y enviar a través de AJAX (5)
Estoy usando ajax para enviar un formulario de varias partes con matriz, campos de texto y archivos.
Añado cada VAR a los datos principales como tal
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);
luego uso la función ajax para enviarla a un archivo PHP para almacenarla dentro de sql DB.
$.ajax({
type: "post",
url: ''php/submittionform.php'',
cache: false,
processData: false,
contentType: false,
data: data,
success: function(request) {$(''#box'').html(request); }
})
Pero en el lado de PHP, la variable arr
, que es una matriz, aparece como una cadena.
Cuando no lo envío con ajax como datos de formulario pero uso la opción simple $.POST
, lo obtengo como una matriz en el lado de PHP, pero luego no puedo enviar los archivos también.
alguna solución?
Esta es una vieja pregunta, pero me encontré con este problema al publicar objetos junto con archivos recientemente. Necesitaba poder publicar un objeto, con propiedades secundarias que también eran objetos y matrices.
La siguiente función recorrerá un objeto y creará el objeto formData correcto.
// 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);
}
});
}
}
Esto convertirá el siguiente json -
{
name: ''starwars'',
year: 1977,
characters: {
good: [''luke'', ''leia''],
bad: [''vader''],
},
}
en los siguientes FormData
name, starwars
year, 1977
characters[good][], luke
characters[good][], leia
characters[bad][], vader
La siguiente versión es válida para el modelo que contiene arays de valores simples:
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;
}
También puede enviar una matriz a través de FormData
esta manera:
var formData = new FormData;
var arr = [''this'', ''is'', ''an'', ''array''];
for (var i = 0; i < arr.length; i++) {
formData.append(''arr[]'', arr[i]);
}
Entonces puede escribir arr[]
la misma forma que lo hace con un simple formulario HTML. En el caso de PHP, debería funcionar.
Puede encontrar este artículo útil: ¿Cómo pasar una matriz dentro de una cadena de consulta?
Tienes varias opciones:
Convierta a una cadena JSON, luego analícelo en PHP (recomendado)
JS
var json_arr = JSON.stringify(arr);
PHP
$arr = json_decode($_POST[''arr'']);
O usa el método de @ Curios
Envío de una matriz a través de FormData
.
No recomendado: serializar los datos con, luego deserializar en PHP
JS
// Use <#> or any other delimiter you want
var serial_arr = arr.join("<#>");
PHP
$arr = explode("<#>", $_POST[''arr'']);
Versión de mecanografiado:
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;
}
}
Utilizando:
let formData = Utility.convertModelToFormData(model);