我怎样才能将我的JS对象转换为FormData?
我这样做的原因是,我有一个用~100个表单字段值构造的对象。
var item = {
description: 'Some Item',
price : '0.00',
srate : '0.00',
color : 'red',
...
...
}
现在我被要求将上传文件功能添加到我的表单,当然,通过JSON是不可能的,所以我计划移动到FormData。那么有什么方法可以将我的JS对象转换为FormData呢?
这个方法将一个JS对象转换为一个FormData:
function convertToFormData(params) {
return Object.entries(params)
.reduce((acc, [key, value]) => {
if (Array.isArray(value)) {
value.forEach((v, k) => acc.append(`${key}[${k}]`, value));
} else if (typeof value === 'object' && !(value instanceof File) && !(value instanceof Date)) {
Object.entries(value).forEach((v, k) => acc.append(`${key}[${k}]`, value));
} else {
acc.append(key, value);
}
return acc;
}, new FormData());
}
如果您有一个对象,您可以轻松地创建一个FormData对象,并将该对象的名称和值附加到FormData。
你还没有发布任何代码,所以这是一个通用的例子;
var form_data = new FormData();
for ( var key in item ) {
form_data.append(key, item[key]);
}
$.ajax({
url : 'http://example.com/upload.php',
data : form_data,
processData : false,
contentType : false,
type: 'POST'
}).done(function(data){
// do stuff
});
在MDN的文档中有更多的例子
其他的答案对我来说是不完整的。我从@Vladimir Novopashin的回答开始修改。以下是我需要的东西和我发现的bug:
文件支持
支持数组
Bug:复杂对象内的文件需要添加。prop而不是[prop]。例如,formData。附加('照片[0][文件]',文件)不工作在谷歌chrome,而
formData.append('照片[0]。文件',文件)工作
忽略对象中的某些属性
下面的代码应该可以在IE11和常绿浏览器上运行。
function objectToFormData(obj, rootName, ignoreList) {
var formData = new FormData();
function appendFormData(data, root) {
if (!ignore(root)) {
root = root || '';
if (data instanceof File) {
formData.append(root, data);
} else if (Array.isArray(data)) {
for (var i = 0; i < data.length; i++) {
appendFormData(data[i], root + '[' + i + ']');
}
} else if (typeof data === 'object' && data) {
for (var key in data) {
if (data.hasOwnProperty(key)) {
if (root === '') {
appendFormData(data[key], key);
} else {
appendFormData(data[key], root + '.' + key);
}
}
}
} else {
if (data !== null && typeof data !== 'undefined') {
formData.append(root, data);
}
}
}
}
function ignore(root){
return Array.isArray(ignoreList)
&& ignoreList.some(function(x) { return x === root; });
}
appendFormData(obj, rootName);
return formData;
}
也许你正在寻找这个,一个代码,接收你的javascript对象,从它创建一个FormData对象,然后POST它到你的服务器使用新的Fetch API:
let myJsObj = {'someIndex': 'a value'};
let datos = new FormData();
for (let i in myJsObj){
datos.append( i, myJsObj[i] );
}
fetch('your.php', {
method: 'POST',
body: datos
}).then(response => response.json())
.then(objson => {
console.log('Success:', objson);
})
.catch((error) => {
console.error('Error:', error);
});
下面是一个非常简单的TypeScript实现,基于@Vladimir Novopashin和@developer033的回答。打印稿操场
type Serializeable =
| string
| number
| boolean
| null
| Date
| File
| { [x: string | number]: Serializeable }
| Array<Serializeable>;
function serialize(
data: Serializeable,
parentKey = '',
formData: FormData = new FormData()
): FormData {
if ( typeof data === 'string') {
formData.append(parentKey, data);
} else if ( typeof data === 'number') {
formData.append(parentKey, data.toString());
} else if ( typeof data === 'boolean') {
formData.append(parentKey, data ? 'true' : 'false');
} else if (data === null) {
formData.append(parentKey, 'null');
} else if (data instanceof Date) {
formData.append(parentKey, data.toISOString());
} else if (data instanceof File) {
formData.append(parentKey, data);
} else {
// Arrays and objects
Object.entries(data).forEach((entry: [string | number, Serializeable]) => {
const [key, value] = entry;
serialize(value, parentKey ? `${parentKey}[${key}]` : key.toString(), formData);
});
}
return formData;
}