I have a simple HTML form that sends an selected file via AJAX to an API endpoint.
If I do the following steps:
I would just check file.lastModified between the upload button clicks and if different reset the form values.
https://developer.mozilla.org/en-US/docs/Web/API/File/lastModified
A better solution would be to read the file into an ArrayBuffer and upload that.
A quick workaround would be to include a complete
parameter to AJAX call (or any equivalent of a finally
call that always gets invoked) and add code that resets the form. I've noticed that attaching the file again solves it. While I appreciate it's not a real solution to the problem, it does provide handling or rather avoidance of that error.
This way, if the user for any reason needs to re-upload the file, they'll have to choose the file again.
Example below:
$.ajax({
url: this.action,
type: this.method,
data: this.data,
success: function (response) {
// success scenario
},
error: function (result) {
// error scenario
},
complete: function (data) {
$('#uploadForm')[0].reset(); // this will reset the form fields
}
});
Just reset the input type file after prompt messages or processing the data
$('#file').val("");
$("#id_of_your_file_input").click(function(){
$("#id_of_your_file_input").val('');
});
Just add the above jQuery script to handle this browser exception. What it does is clearing the file input every time someone clicks on it, so that it will remove the current selection.
No, if the user has changed file it already another file so you can't (should not) get access to this file without user explicit user action otherwise it would be a security issue.
You can save the file in the memory when user uploads it.
document.getElementById('fileInput').addEventListener('change', function() {
saveFileConentInMemory(this.files[0].arrayBuffer());
});
And when the user press the "Send" button just get this content from memory and send it
button.addEventListener('click', () => {
const file = getFileContentFromMemeory();
send(file);
})
Yes, you can't be sure that you send the latest version of the file but you should be sure that you send the content which was uploaded.
Also, you should aware of memory consumption and asynchronous API of reading file (so you still can get this error about changed content even when you write it in memory)
I managed to get a more descriptive error using the javascript File Reader. After the the file is changed and the button is pressed for the second time, the FileReader throws a somewhat more descriptive message:
DOMException: The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.
At least this is an error that can be caught and displayed to the user, so they are aware that they need to re-select the file.
Here is the snippet:
<html>
<head>
<title>Test</title>
<script type='text/javascript'>
document.addEventListener("DOMContentLoaded", function(){
const button = document.querySelector('#btnSubmit');
button.addEventListener('click', () => {
let inputElement = document.getElementById('csvfile');
for (let i = 0; i < inputElement.files.length; i++) {
const file = inputElement.files[i];
console.log(file);
const reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = function (evt) {
console.log(evt.target.result);
}
reader.onerror = function (err) {
// read error caught here
console.log(err);
console.log(err.target.error);
}
}
});
});
</script>
</head>
<body>
<form enctype="multipart/form-data" action="" method="post" id='theForm'>
<input type="file" name="csvfile" id="csvfile" value="" />
<input type="button" name="uploadCSV" value="Upload" id='btnSubmit'/>
</form>
</body>
</html>
It seems that there is no way around this at the moment (June 2020). There is an open bug on Chromium:
https://bugs.chromium.org/p/chromium/issues/detail?id=1084880&q=ERR_UPLOAD_FILE_CHANGED&can=2