将数组附加到 FormData 并通过 AJAX 发送
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16104078/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
appending array to FormData and send via AJAX
提问by shultz
I'm using ajax to submit a multipart form with array, text fields and files.
我正在使用 ajax 提交一个包含数组、文本字段和文件的多部分表单。
I append each VAR to the main data as so
我将每个 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);
then I use the ajax function to send it to a PHP file to store inside sql DB.
然后我使用 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); }
})
But on the PHP side, the arrvariable, which is an array appears as a string.
但是在 PHP 端,arr变量,它是一个数组,显示为一个字符串。
When I don't send it with ajax as Form data but use the simple $.POSToption I do get it as an array on the PHP side, but then I can't send the files as well.
当我不使用 ajax 作为表单数据发送它而是使用简单$.POST选项时,我确实将它作为 PHP 端的数组获取,但是我也无法发送文件。
any solutions?
任何解决方案?
采纳答案by Richard de Wit
You have several options:
您有多种选择:
Convert it to a JSON string, then parse it in PHP (recommended)
将其转换为JSON字符串,然后在PHP中解析(推荐)
JS
JS
var json_arr = JSON.stringify(arr);
PHP
PHP
$arr = json_decode($_POST['arr']);
Or use @Curios's method
或者使用@Curios 的方法
Sending an array via FormData.
通过FormData.
Not recommended: Serialize the data with, then deserialize in PHP
不推荐:序列化数据,然后在 PHP 中反序列化
JS
JS
// Use <#> or any other delimiter you want
var serial_arr = arr.join("<#>");
PHP
PHP
$arr = explode("<#>", $_POST['arr']);
回答by Oleg
You can also send an array via FormDatathis way:
您还可以通过FormData这种方式发送数组:
var formData = new FormData;
var arr = ['this', 'is', 'an', 'array'];
for (var i = 0; i < arr.length; i++) {
formData.append('arr[]', arr[i]);
}
So you can write arr[]the same way as you do it with a simple HTML form. In case of PHP it should work.
因此,您可以arr[]像使用简单的 HTML 表单一样编写。在 PHP 的情况下,它应该可以工作。
You may find this article useful: How to pass an array within a query string?
您可能会发现这篇文章很有用:如何在查询字符串中传递数组?
回答by VtoCorleone
This is an old question but I ran into this problem with posting objects along with files recently. I needed to be able to post an object, with child properties that were objects and arrays as well.
这是一个老问题,但我最近在发布对象和文件时遇到了这个问题。我需要能够发布一个对象,其子属性也是对象和数组。
The function below will walk through an object and create the correct formData object.
下面的函数将遍历一个对象并创建正确的 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);
}
});
}
}
This will convert the following json -
这将转换以下 json -
{
name: 'starwars',
year: 1977,
characters: {
good: ['luke', 'leia'],
bad: ['vader'],
},
}
into the following FormData
进入下面的 FormData
name, starwars
year, 1977
characters[good][], luke
characters[good][], leia
characters[bad][], vader
回答by Mohammad Dayyan
Typescript version:
打字稿版本:
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;
}
}
Using:
使用:
let formData = Utility.convertModelToFormData(model);
回答by HamidNE
add all type inputs to FormData
将所有类型输入添加到 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]) ;
}
回答by YackY
If you have nested objects and arrays, best way to populate FormData object is using recursion.
如果您有嵌套对象和数组,填充 FormData 对象的最佳方法是使用递归。
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);
}
}
回答by dikirill
Based on @YackY answer shorter recursion version:
基于@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);
}
}
Usage example:
用法示例:
var data = {a: '1', b: 2, c: {d: '3'}};
var formData = new FormData();
createFormData(formData, 'data', data);
Sent data:
发送数据:
data[a]=1&
data[b]=2&
data[c][d]=3
回答by Megabyte
Next version valid for model containing arays of simple values:
下一个版本对包含简单值数组的模型有效:
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;
}

