我怎样才能将我的JS对象转换为FormData?
我这样做的原因是,我有一个用~100个表单字段值构造的对象。
var item = {
description: 'Some Item',
price : '0.00',
srate : '0.00',
color : 'red',
...
...
}
现在我被要求将上传文件功能添加到我的表单,当然,通过JSON是不可能的,所以我计划移动到FormData。那么有什么方法可以将我的JS对象转换为FormData呢?
将处理嵌套数组和对象的解决方案。有人可能会觉得有用
function add_form_data(form_data,key,item,arr){
if(typeof(item)==='object' && item && item.constructor===Array){
for(var i=0;i<item.length;i++){
var item2=item[i];
var key2=key+'[' + i +']';
if(arr){
key2=key+'[' + key2 +']';
}
add_form_data(form_data,key2,item2,true);
}
}else if(typeof(item)==='object' && item){
for ( var key2 in item ) {
var item2=item[key2];
if(arr){
key2=key+'[' + key2 +']';
}
add_form_data(form_data,key2,item2,arr);
}
}else{
form_data.append(key,item);
}
}
使用
var form_data = new FormData();
add_form_data(form_data,null,json_data);// provide json_data here
var string_url_data=new URLSearchParams(form_data).toString();// if query string is needed
递归地
const toFormData = (f => f(f))(h => f => f(x => h(h)(f)(x)))(f => fd => pk => d => {
if (d instanceof Object) {
Object.keys(d).forEach(k => {
const v = d[k]
if (pk) k = `${pk}[${k}]`
if (v instanceof Object && !(v instanceof Date) && !(v instanceof File)) {
return f(fd)(k)(v)
} else {
fd.append(k, v)
}
})
}
return fd
})(new FormData())()
let data = {
name: 'John',
age: 30,
colors: ['red', 'green', 'blue'],
children: [
{ name: 'Max', age: 3 },
{ name: 'Madonna', age: 10 }
]
}
console.log('data', data)
document.getElementById("data").insertAdjacentHTML('beforeend', JSON.stringify(data))
let formData = toFormData(data)
for (let key of formData.keys()) {
console.log(key, formData.getAll(key).join(','))
document.getElementById("item").insertAdjacentHTML('beforeend', `<li>${key} = ${formData.getAll(key).join(',')}</li>`)
}
<p id="data"></p>
<ul id="item"></ul>
使用ES6和更函数式的编程方法@adeneo的答案可能是这样的:
function getFormData(object) {
const formData = new FormData();
Object.keys(object).forEach(key => formData.append(key, object[key]));
return formData;
}
或者使用.reduce()和箭头函数:
const getFormData = object => Object.keys(object).reduce((formData, key) => {
formData.append(key, object[key]);
return formData;
}, new FormData());
我参考了古德拉丹的回答。我用Typescript格式编辑了一下。
class UtilityService {
private appendFormData(formData, data, rootName) {
let root = rootName || '';
if (data instanceof File) {
formData.append(root, data);
} else if (Array.isArray(data)) {
for (var i = 0; i < data.length; i++) {
this.appendFormData(formData, data[i], root + '[' + i + ']');
}
} else if (typeof data === 'object' && data) {
for (var key in data) {
if (data.hasOwnProperty(key)) {
if (root === '') {
this.appendFormData(formData, data[key], key);
} else {
this.appendFormData(formData, data[key], root + '.' + key);
}
}
}
} else {
if (data !== null && typeof data !== 'undefined') {
formData.append(root, data);
}
}
}
getFormDataFromObj(data) {
var formData = new FormData();
this.appendFormData(formData, data, '');
return formData;
}
}
export let UtilityMan = new UtilityService();