我怎样才能将我的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()); }

其他回答

你可以简单地安装qs:

npm i qs

简单的导入:

import qs from 'qs'

将对象传递给qs.stringify():

var item = {
   description: 'Some Item',
   price : '0.00',
   srate : '0.00',
   color : 'red',
   ...
   ...
}

qs.stringify(item)

如果您有一个对象,您可以轻松地创建一个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;
}