I’m trying to upload a video file via AJAX, a XMLHttpRequest and PHP to display the upload progress but the request throws an abort and quickly refreshes the page if I try to upload something.
If I just send the POST request to the PHP file via the form, without AJAX/XMLHttpRequest, the file upload works. But a progress bar would be handy…
The code consists of the HTML form, the JavaScript functions and the PHP upload (I omitted the progress bar HTML code to make it more readable).
HTML:
<form action="" method="post" enctype="multipart/form-data" id="uploadForm"> <input type="file" accept="video/mp4" class="form-control" name="fileToUpload" id="fileToUpload" onclick="closeFileToBigAlert()" onchange="checkFile(this.files)" required> <button onclick="uploadFile()" class="btn">Upload</button> </form>
JavaScript:
function uploadFile(){ // Get the file var file = document.getElementById("fileToUpload").files[0]; // Create FormData object and append file as "file" var formData = new FormData(); formData.append("file",file); // Create XMLHttpRequest object var ajax = new XMLHttpRequest(); // Add Event Listeners ajax.upload.addEventListener("upload-progress", progressHandler, false); ajax.addEventListener("load", completeHandler, false); ajax.addEventListener("error", errorHandler, false); ajax.addEventListener("abort", abortHandler, false); // Open upload.php and send POST request ajax.open("POST", "upload.php"); ajax.send(formData); } function progressHandler(event){ // Calculate percentage var percent = (event.loaded / event.total) * 100; // Insert percentage number into progress bar var bar = document.getElementById("upload-progress"); bar.setAttribute("aria-valuenow", Math.round(percent)); bar.setAttribute("style", "width: "+ Math.round(percent) +"%"); bar.innerHTML = Math.round(percent) + "%"; } function completeHandler(event){ document.getElementById("status").innerHTML = event.target.responseText; var bar = document.getElementById("upload-progress"); bar.setAttribute("aria-valuenow", "0"); bar.setAttribute("style", "width: 0%"); bar.innerHTML = "0%"; } function errorHandler(event){ document.getElementById("status").innerHTML = "Upload Failed"; } function abortHandler(event){ document.getElementById("status").innerHTML = "Upload Aborted"; }
And PHP:
$fileName = $_FILES["file"]["name"]; $fileTmpLoc = $_FILES["file"]["tmp_name"]; $fileType = $_FILES["file"]["type"]; $fileSize = $_FILES["file"]["size"]; $fileErrorMsg = $_FILES["file"]["error"]; if(move_uploaded_file($fileTmpLoc, "uploads/$fileName")){ echo "$fileName upload is complete"; } else { echo "move_uploaded_file function failed"; }
Any ideas why the request immediately aborts and refreshes the page? The PHP log is empty.
The environment is local via XAMPP
Advertisement
Answer
You’re submitting the form. The JS starts but then the form submits and you navigate to a new page (which aborts all the JS from the previous page).
- Remove the
onclick
attribuete - Bind a submit event handler on the form
- Prevent the default behaviour that comes with form submissions
Such:
document.querySelector(`#uploadForm`).addEventListener('submit', event => { event.preventDefault(); // Do everything else });