如何在onchange函数中使用promise获取文件上传的json?

时间:2019-04-27 03:18:51

标签: javascript promise filereader

我建立了一个将表单转换为json的网站,但我需要将图像文件上传到base64(string)并添加到json,但它仅返回url,它在console.log()中成功,但在赋值时不成功是我的代码

<form id="test" action="#" method="post">
    <div class="row">
        <div class="form-group">
            <label>First Name</label>
            <input name="namadepan" type="text" placeholder="Enter First Name Here.." class="form-control">
        </div>

    <div class="form-group">
        <label for="gambar">Foto</label>
        <input type="file"  class="form-control" name ="gambar" id="imagefile" value="Import"  onchange="toJSONString(document.getElementById('test'))" />
    </div>
    <p>
        <input type="submit" value="Send" class="btn btn-primary btn-block" />
    </p>
</form>

<textarea id="output"  class="form-control"></textarea>

这是脚本

function toJSONString(form) {
    var obj = {};
    var elements = form.querySelectorAll("input, select, textarea");
    for (var i = 0; i < elements.length; ++i) {
        var element = elements[i];
        var name = element.name;
        var value = element.value;

        if (element.type == "file") {
            var p = new Promise(function (resolve) {
                var reader = new FileReader();
                reader.onload = function () {
                    code = reader.result;
                    resolve(code);
                    console.log(reader.result);
                };
                reader.readAsDataURL(element.files[0]);
            });

            p.then(function (result) {
                value = result;
            })
        }

        if (name) {
            obj[name] = value;
        }
    }
    //return JSON.stringify( obj );
    document.getElementById("output").value = JSON.stringify(obj);
}

上面的结果是

{"namadepan":"johndoe","gambar":"C:\\fakepath\\t2.jpg"}

我期望什么

{"namadepan":"johndoe","gambar":"data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAUDBAQEAwUE"}

1 个答案:

答案 0 :(得分:0)

C:\\fakepath\\t2.jpg的值来自element.value

您之所以会看到此消息,是因为您在兑现承诺之前就已经存储了值。

要正确等待承诺,请参见以下内容:

请注意,toJSONString现在是async函数

async function toJSONString(form) {
    var obj = {};
    var elements = form.querySelectorAll("input, select, textarea");
    for (var i = 0; i < elements.length; ++i) {
        var element = elements[i];
        var name = element.name;

        // check `name`
        if(name) {
            // await the Promise here
            var value = await new Promise((resolve, reject) => {
                if (element.type == "file") {
                    var reader = new FileReader();

                    reader.onload = function () {
                        // resolve to data url
                        resolve(reader.result);
                    };
                    
                    reader.readAsDataURL(element.files[0]);
                } else {
                
                    // resolve to value
                    resolve(element.value);
                }
            });

            // store the value after the promise is resolved.
            obj[name] = value;
        }
        
    }
    //return JSON.stringify( obj );
    document.getElementById("output").value = JSON.stringify(obj);
}
<form id="test" action="#" method="post">
    <div class="row">
        <div class="form-group">
            <label>First Name</label>
            <input name="namadepan" type="text" placeholder="Enter First Name Here.." class="form-control">
        </div>

    <div class="form-group">
        <label for="gambar">Foto</label>
        <input type="file"  class="form-control" name ="gambar" id="imagefile" value="Import"  onchange="toJSONString(document.getElementById('test'))" />
    </div>
    <p>
        <input type="submit" value="Send" class="btn btn-primary btn-block" />
    </p>
</form>

<textarea id="output"  class="form-control"></textarea>