Kam*_*med 93 javascript jquery multipartform-data form-data
我怎样才能将我的JS对象转换为FormData?
我想要这样做的原因是,我有一个我用~100表单字段值构造的对象.
var item = {
description: 'Some Item',
price : '0.00',
srate : '0.00',
color : 'red',
...
...
}
Run Code Online (Sandbox Code Playgroud)
现在我被要求将上传文件功能添加到我的表单中,当然这是不可能通过JSON,因此我打算转移到FormData.那么有什么方法可以将我的JS对象转换为FormData?
ade*_*neo 127
如果您有一个对象,则可以轻松创建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
});
Run Code Online (Sandbox Code Playgroud)
MDN文档中有更多示例
Jac*_*zen 63
使用ES6和更多功能编程方法@ adeneo的答案可能如下所示:
function getFormData(object) {
const formData = new FormData();
Object.keys(object).forEach(key => formData.append(key, object[key]));
return formData;
}
Run Code Online (Sandbox Code Playgroud)
或者使用.reduce()和箭头功能:
getFormData = object => Object.keys(object).reduce((formData, key) => {
formData.append(key, object[key]);
return formData;
}, new FormData());
Run Code Online (Sandbox Code Playgroud)
Vla*_*hin 32
此函数将对象的所有数据添加到FormData
来自@ developer033的ES6版本:
function buildFormData(formData, data, parentKey) {
if (data && typeof data === 'object' && !(data instanceof Date) && !(data instanceof File)) {
Object.keys(data).forEach(key => {
buildFormData(formData, data[key], parentKey ? `${parentKey}[${key}]` : key);
});
} else {
const value = data == null ? '' : data;
formData.append(parentKey, value);
}
}
function jsonToFormData(data) {
const formData = new FormData();
buildFormData(formData, data);
return formData;
}
const my_data = {
num: 1,
falseBool: false,
trueBool: true,
empty: '',
und: undefined,
nullable: null,
date: new Date(),
name: 'str',
another_object: {
name: 'my_name',
value: 'whatever'
},
array: [
{
key1: {
name: 'key1'
}
}
]
};
jsonToFormData(my_data)
Run Code Online (Sandbox Code Playgroud)
jQuery版本:
function appendFormdata(FormData, data, name){
name = name || '';
if (typeof data === 'object'){
$.each(data, function(index, value){
if (name == ''){
appendFormdata(FormData, value, index);
} else {
appendFormdata(FormData, value, name + '['+index+']');
}
})
} else {
FormData.append(name, data);
}
}
var formData = new FormData(),
your_object = {
name: 'test object',
another_object: {
name: 'and other objects',
value: 'whatever'
}
};
appendFormdata(formData, your_object);
Run Code Online (Sandbox Code Playgroud)
井上智*_*上智文 14
function toFormData(o) {
return Object.entries(o).reduce((d,e) => (d.append(...e),d), new FormData())
}
var object = {
username: 'JohnDoe',
file: new File(['foo'], 'foo.txt', {type: 'text/plain'})
}
fetch('https://httpbin.org/post', {
method: 'POST',
body: toFormData(object)
}).then(r => r.json()).then(console.log)Run Code Online (Sandbox Code Playgroud)
Gud*_*ain 10
其他答案对我来说不完整.我从@Vladimir Novopashin回答并修改了它.以下是我需要的东西以及我发现的错误:
.prop而不是[prop].例如,formData.append('photos[0][file]', file)没有对谷歌浏览器工作,而
formData.append('photos[0].file', file)工作以下代码应适用于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;
}
Run Code Online (Sandbox Code Playgroud)
Axios 现在支持将对象自动序列化为 FormData
从版本 0.27 开始,如果请求 Content-Type 标头设置为 multipart/form-data,Axios 支持自动对象序列化为 FormData 对象。阅读更多
以下解决方案处理嵌套对象、数组和文件。
const buildFormData = (formData: FormData, data: FormVal, parentKey?: string) => {
if (Array.isArray(data)) {
data.forEach((el) => {
buildFormData(formData, el, parentKey)
})
} else if (typeof data === "object" && !(data instanceof File)) {
Object.keys(data).forEach((key) => {
buildFormData(formData, (data as FormDataNest)[key], parentKey ? `${parentKey}.${key}` : key)
})
} else {
if (isNil(data)) {
return
}
let value = typeof data === "boolean" || typeof data === "number" ? data.toString() : data
formData.append(parentKey as string, value)
}
}
export const getFormData = (data: Record<string, FormDataNest>) => {
const formData = new FormData()
buildFormData(formData, data)
return formData
}
Run Code Online (Sandbox Code Playgroud)
类型
type FormDataPrimitive = string | Blob | number | boolean
interface FormDataNest {
[x: string]: FormVal
}
type FormVal = FormDataNest | FormDataPrimitive
Run Code Online (Sandbox Code Playgroud)
我有一个场景,在构建表单数据时,必须以线性方式序列化嵌套JSON,因为这是服务器期望值的方式.所以,我写了一个小的递归函数来转换JSON,如下所示:
{
"orderPrice":"11",
"cardNumber":"************1234",
"id":"8796191359018",
"accountHolderName":"Raj Pawan",
"expiryMonth":"02",
"expiryYear":"2019",
"issueNumber":null,
"billingAddress":{
"city":"Wonderland",
"code":"8796682911767",
"firstname":"Raj Pawan",
"lastname":"Gumdal",
"line1":"Addr Line 1",
"line2":null,
"state":"US-AS",
"region":{
"isocode":"US-AS"
},
"zip":"76767-6776"
}
}
Run Code Online (Sandbox Code Playgroud)
进入这样的事情:
{
"orderPrice":"11",
"cardNumber":"************1234",
"id":"8796191359018",
"accountHolderName":"Raj Pawan",
"expiryMonth":"02",
"expiryYear":"2019",
"issueNumber":null,
"billingAddress.city":"Wonderland",
"billingAddress.code":"8796682911767",
"billingAddress.firstname":"Raj Pawan",
"billingAddress.lastname":"Gumdal",
"billingAddress.line1":"Addr Line 1",
"billingAddress.line2":null,
"billingAddress.state":"US-AS",
"billingAddress.region.isocode":"US-AS",
"billingAddress.zip":"76767-6776"
}
Run Code Online (Sandbox Code Playgroud)
服务器将接受采用此转换格式的表单数据.
这是功能:
function jsonToFormData (inJSON, inTestJSON, inFormData, parentKey) {
// http://stackoverflow.com/a/22783314/260665
// Raj: Converts any nested JSON to formData.
var form_data = inFormData || new FormData();
var testJSON = inTestJSON || {};
for ( var key in inJSON ) {
// 1. If it is a recursion, then key has to be constructed like "parent.child" where parent JSON contains a child JSON
// 2. Perform append data only if the value for key is not a JSON, recurse otherwise!
var constructedKey = key;
if (parentKey) {
constructedKey = parentKey + "." + key;
}
var value = inJSON[key];
if (value && value.constructor === {}.constructor) {
// This is a JSON, we now need to recurse!
jsonToFormData (value, testJSON, form_data, constructedKey);
} else {
form_data.append(constructedKey, inJSON[key]);
testJSON[constructedKey] = inJSON[key];
}
}
return form_data;
}
Run Code Online (Sandbox Code Playgroud)
调用:
var testJSON = {};
var form_data = jsonToFormData (jsonForPost, testJSON);
Run Code Online (Sandbox Code Playgroud)
我正在使用testJSON来查看转换后的结果,因为我无法提取form_data的内容.AJAX发帖:
$.ajax({
type: "POST",
url: somePostURL,
data: form_data,
processData : false,
contentType : false,
success: function (data) {
},
error: function (e) {
}
});
Run Code Online (Sandbox Code Playgroud)
这是一个简短而甜蜜的解决方案,使用Object.entries()它甚至可以处理您的嵌套对象。
// If this is the object you want to convert to FormData...
const item = {
description: 'First item',
price: 13,
photo: File
};
const formData = new FormData();
Object.entries(item).forEach(([key, value]) => {
formData.append(key, value);
});
// At this point, you can then pass formData to your handler method
Run Code Online (Sandbox Code Playgroud)
Object.entries()在这里阅读更多信息- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
很抱歉回答晚了,但我一直在努力解决这个问题,因为 Angular 2 目前不支持文件上传。因此,方法是发送一个XMLHttpRequestwith FormData。所以,我创建了一个函数来完成它。我正在使用Typescript。要将其转换为Javascript,只需删除数据类型声明。
/**
* Transforms the json data into form data.
*
* Example:
*
* Input:
*
* fd = new FormData();
* dob = {
* name: 'phone',
* photos: ['myphoto.jpg', 'myotherphoto.png'],
* price: '615.99',
* color: {
* front: 'red',
* back: 'blue'
* },
* buttons: ['power', 'volup', 'voldown'],
* cameras: [{
* name: 'front',
* res: '5Mpx'
* },{
* name: 'back',
* res: '10Mpx'
* }]
* };
* Say we want to replace 'myotherphoto.png'. We'll have this 'fob'.
* fob = {
* photos: [null, <File object>]
* };
* Say we want to wrap the object (Rails way):
* p = 'product';
*
* Output:
*
* 'fd' object updated. Now it will have these key-values "<key>, <value>":
*
* product[name], phone
* product[photos][], myphoto.jpg
* product[photos][], <File object>
* product[color][front], red
* product[color][back], blue
* product[buttons][], power
* product[buttons][], volup
* product[buttons][], voldown
* product[cameras][][name], front
* product[cameras][][res], 5Mpx
* product[cameras][][name], back
* product[cameras][][res], 10Mpx
*
* @param {FormData} fd FormData object where items will be appended to.
* @param {Object} dob Data object where items will be read from.
* @param {Object = null} fob File object where items will override dob's.
* @param {string = ''} p Prefix. Useful for wrapping objects and necessary for internal use (as this is a recursive method).
*/
append(fd: FormData, dob: Object, fob: Object = null, p: string = ''){
let apnd = this.append;
function isObj(dob, fob, p){
if(typeof dob == "object"){
if(!!dob && dob.constructor === Array){
p += '[]';
for(let i = 0; i < dob.length; i++){
let aux_fob = !!fob ? fob[i] : fob;
isObj(dob[i], aux_fob, p);
}
} else {
apnd(fd, dob, fob, p);
}
} else {
let value = !!fob ? fob : dob;
fd.append(p, value);
}
}
for(let prop in dob){
let aux_p = p == '' ? prop : `${p}[${prop}]`;
let aux_fob = !!fob ? fob[prop] : fob;
isObj(dob[prop], aux_fob, aux_p);
}
}
Run Code Online (Sandbox Code Playgroud)
尝试如下的JSON.stringify函数
var postData = JSON.stringify(item);
var formData = new FormData();
formData.append("postData",postData );
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
131367 次 |
| 最近记录: |