appending array to FormData and send via AJAX
我使用Ajax提交一个包含数组、文本字段和文件的多部分表单。
因此,我将每个var附加到主数据中
1 2 3 4 5 6 7 8 9 10 11 | 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数据库中。
1 2 3 4 5 6 7 8 9 | $.ajax({ type:"post", url: 'php/submittionform.php', cache: false, processData: false, contentType: false, data: data, success: function(request) {$('#box').html(request); } }) |
但在PHP方面,作为数组的
当我不使用Ajax作为表单数据发送它,而是使用简单的
有什么解决办法吗?
您也可以通过
1 2 3 4 5 | var formData = new FormData; var arr = ['this', 'is', 'an', 'array']; for (var i = 0; i < arr.length; i++) { formData.append('arr[]', arr[i]); } |
因此,您可以像使用简单的HTML表单那样编写
您可能会发现本文很有用:如何在查询字符串中传递数组?
您有几个选项:
将其转换为JSON字符串,然后用PHP解析(推荐)JS
1 | var json_arr = JSON.stringify(arr); |
PHP
1 | $arr = json_decode($_POST['arr']); |
或者使用@curios的方法
通过
JS
1 2 | // Use <#> or any other delimiter you want var serial_arr = arr.join("<#>"); |
PHP
1 | $arr = explode("<#>", $_POST['arr']); |
类型脚本版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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; } } |
使用:
1 | let formData = Utility.convertModelToFormData(model); |
这是一个老问题,但我最近遇到了这个问题,即随文件一起发布对象。我需要能够发布一个对象,以及对象和数组的子属性。
下面的函数将遍历一个对象并创建正确的FormData对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 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-
1 2 3 4 5 6 7 8 | { name: 'starwars', year: 1977, characters: { good: ['luke', 'leia'], bad: ['vader'], }, } |
进入以下表单数据
1 2 3 4 5 | name, starwars year, 1977 characters[good][], luke characters[good][], leia characters[bad][], vader |
将所有类型输入添加到FormData
1 2 3 4 5 6 | 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]) ; } |
如果有嵌套的对象和数组,填充FormData对象的最佳方法是使用递归。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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; } |