我有一个使用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的帖子与提交表单有何关系。但我会继续消化。感谢那些正在寻找的人。
答案 0 :(得分:0)
这是有效的方法:
BETWEEN