如何在xhmhttprequest完成之前暂停表单提交

时间:2019-01-31 23:35:15

标签: javascript bootstrap-4 xmlhttprequest

我有一个使用Boostrap和纯Javascipt的Flask Web应用程序。提交表单后,我执行xmlhttprequest将文件上传到s3。问题是页面在xhr返回之前重新加载并取消了我的请求。

这个问题经常被问到,我已经尝试了所见过的所有解决方案(在这个问题上需要10个小时!)。唯一可行的解​​决方案是在我的Flask应用中等待3秒。这允许xhr请求在页面重新加载之前进行处理。我当前的代码获取请求,然后挂起。我无法继续下去。

document.getElementById("accountForm").onsubmit = function (e) {
    e.preventDefault();
    uploadfile();
};

Tried every permutation of this I can find....
Tried changing to'accountForm' and 'onsubmit'
Tried 'onclick'...

JavaScript

document.getElementById("accountForm").onsubmit = function (e) {
    e.preventDefault();
    uploadfile();
};

HTML

    <form method="POST" action="" enctype="multipart/form-data" id="accountForm">
        <input id="csrf_token" name="csrf_token" type="hidden" value="IjE1MjE0ZmM1OGMxNDI1NzMxZGY5N2E2MWFkMjExMDJmYmY3NjczMGEi.XFOE9Q.HVCiO1aeu0zWXG9nL0B1Z5mgnkE">
        <fieldset class="form-group">
            <legend class="border-bottom mb-4">Account Info</legend>
            <div class="form-group">
                <label class="form-control-label" for="username">Username</label>


                    <input class="form-control form-control-lg" id="username" name="username" required type="text" value="bill">

            </div>
            <div class="form-group">
                <label class="form-control-label" for="email">Email</label>

                    <input class="form-control form-control-lg" id="email" name="email" required type="text" value="bill@gmail.com">

            </div>
            <div class="form-group">
                <label for="picture">Update Profile Picture</label>
                <input class="form-control-file" id="picture" name="picture" type="file">

            </div>
        </fieldset>
        <div class="form-group">
            <input class="btn btn-outline-info" id="submit" name="submit" type="submit" value="Update">
        </div>
    </form>

javascript

function uploadfile() {
    console.log("uploadfile main function called")
    /* Check file exist and call for temporary signature */
    const files = document.getElementById('picture').files;
    const file = files[0];
    if (!file) {
        return;
    }
    getSignedRequest(file);
    /* Function to get the signature from the flask app */
    console.log('Getting Signed request')
    function getSignedRequest(file) {
        const xhttp = new XMLHttpRequest();
        //xhr.open('GET',`/sign-s3/?file-name=${file.name}&file-type=${file.type}`);
        xhttp.onreadystatechange = function () {
            console.log('ppReg: ' + this.readyState + " " + this.status)
            if (this.readyState == 4 && this.status == 200) {
                const response = JSON.parse(this.responseText);
                console.log(this.readyState, this.status)
                uploadFile(file, response.data, response.url);
            }
        };
        xhttp.open('GET', `/s3Request/?file-name=${file.name}&file-type=${file.type}`);
        xhttp.send();
        // xhr.send();
    }
    /* Function to send the file to S3 */
    function uploadFile(file, s3Data, url) {

        console.log('uploading file after ppReq')
        const xreq = new XMLHttpRequest();

        xreq.onreadystatechange = function () {
            console.log('s3Upload: ' + this.readyState + " " + this.status)
            if (this.readyState == 4 && this.status == 204) {
                //const response = JSON.parse(this.responseText);
                //uploadFile(file,response.data,response.url);
                console.log('File upload received by s3')
            }
            // else if (this.readyState == 4 && this.status != 204) {
            //     alert("File upload failed.")

            else {
                // change to alert
                console.log(this.readyState, this.status)
            }
        };
        xreq.open('POST', s3Data.url, true); // set to false but need to change.
        xreq.setRequestHeader('x-amz-acl', 'public-read');
        const postData = new FormData();
        for (key in s3Data.fields) {
            postData.append(key, s3Data.fields[key]);
        }
        postData.append('file', file);
        console.log(postData)
        xreq.send(postData)
        console.log('Data Sent!')

    }
}

我希望不提交表单,然后运行uploadfile()并最终提交表单。在运行uploadfile()之后,当前代码停止。任何帮助都会真的很感激!如果可能的话,我尝试使用普通的JS。

编辑:我同意已经问过类似的问题,但是我已经尝试了所有的解决方案。我是Java语言的新手,所以我不知道建议的讨论Promise的帖子与提交表单有何关系。但我会继续消化。感谢那些正在寻找的人。

1 个答案:

答案 0 :(得分:0)

这是有效的方法:

BETWEEN