0

I need to upload a file by only using vanilla.js, no frameworks are allowed.

Form:

<form id="fileUploadForm" action="fileUpload.php" method="post" enctype="multipart/form-data"> <input type="file" name="fileToUpload" id="fileToUpload"> </form> 

I placed the button outside of the form, because it is at another position in the HTML.

<button id="btnUpload">Upload</button> 

This is the upload Script. I am using FormData to get the form data, as described in this answer.

<script> document.getElementById("btnUpload").addEventListener("click", function() { fileUpload("fileUploadForm"); }); function fileUpload(pFormId) { debugger; var form = document.getElementById(pFormId); var formData = new FormData( form ); //returns no data! var request = getHttpRequest(); request.onreadystatechange = function() { if (request.readyState === 4 && request.status === 200) { console.log("Response Received"); document.getElementById("debug").innerHTML = request.responseText; } }; request.open("POST", "fileUpload.php", true); // request.setRequestHeader("Content-type","application/x-www-form-urlencoded"); request.setRequestHeader("Content-type","multipart/form-data"); formData.append("action","test"); //Add additional POST param request.send(formData); } function getHttpRequest() { let xmlhttp; if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } return xmlhttp; } </script> 

I am using the PHP upload script from here.

<?php $target_dir = "uploads/"; $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]); $uploadOk = 1; $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION)); // Check if image file is a actual image or fake image if(isset($_POST["submit"])) { $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]); if($check !== false) { echo "File is an image - " . $check["mime"] . "."; $uploadOk = 1; } else { echo "File is not an image."; $uploadOk = 0; } } // Check if file already exists if (file_exists($target_file)) { echo "Sorry, file already exists."; $uploadOk = 0; } // Check file size if ($_FILES["fileToUpload"]["size"] > 500000) { echo "Sorry, your file is too large."; $uploadOk = 0; } // Allow certain file formats if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg" && $imageFileType != "gif" ) { echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed."; $uploadOk = 0; } // Check if $uploadOk is set to 0 by an error if ($uploadOk == 0) { echo "Sorry, your file was not uploaded."; // if everything is ok, try to upload file } else { if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) { echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded."; } else { echo "Sorry, there was an error uploading your file."; } } 

I attached the debugger to my javascript and found out that formData is empty and does not contain the file. enter image description here

This is what I get from PHP:

enter image description here Sorry, file already exists.

enter image description here Sorry, only JPG, JPEG, PNG & GIF files are allowed.Sorry, your file was not uploaded.

Even though the file does NOT already exists AND the file format is jpg.


Update:

This is what I get in the developers console network tab:

Request Payload: ------WebKitFormBoundaryKjnjAyPoCQ7MU1x6 Content-Disposition: form-data; name="fileToUpload"; filename="Koala.jpg" Content-Type: image/jpeg ------WebKitFormBoundaryKjnjAyPoCQ7MU1x6-- 

I appreciate any help!

8
  • Check what your browser sends. F12 > network > click the request and check what the parameter names are. Commented Apr 25, 2018 at 11:06
  • Good hint! I update my question. Commented Apr 25, 2018 at 11:07
  • You should not set Content-type header when uploading via FormData Commented Apr 25, 2018 at 11:09
  • @MartinAdámek, Ahh ok, now I get Sorry, your file is too large.Sorry, your file was not uploaded. after commenting request.setRequestHeader("Content-type","multipart/form-data"); out! Thanks! The file is only 750KB big though :/? Commented Apr 25, 2018 at 11:11
  • And what is the size of that file? You probably reached the limit of 500000 bytes Commented Apr 25, 2018 at 11:12

2 Answers 2

1

Just drop the content-type header, that will be set automatically by browser when using FormData. That way content-type will also contain form boundary used to separate form data (the thing like ------WebKitFormBoundaryKjnjAyPoCQ7MU1x6-- that separated the payload data).

Sign up to request clarification or add additional context in comments.

Comments

0

I'd modify the code slightly.

document.getElementById("btnUpload").addEventListener("click", function() { fileUpload("fileUploadForm"); }); 

You're binding the event on click. I'd modify this and attach a submit event to the form.

The closure will get the event target as callback:

document.getElementById("fileUploadForm").addEventListener("submit", function(e) { // <- pay attention to parameter e.preventDefault(); // Prevent the default action so we stay on the same page. fileUpload(e); // pass the event to your function }); 

Now, on to your fileUpload function.

function fileUpload(e) { debugger; var formData = new FormData( e.target ); // pass the event target to FormData which serializes the data var request = getHttpRequest(); request.onreadystatechange = function() { if (request.readyState === 4 && request.status === 200) { console.log("Response Received"); document.getElementById("debug").innerHTML = request.responseText; } }; request.open("POST", "fileUpload.php", true); request.setRequestHeader("Content-type","multipart/form-data"); request.send(formData); } 

Disclaimer: I did not test this at all, so don't copy paste and expect it to work!

2 Comments

This will not work unless you remove the content-type header. The problem is not in passing form reference to FormData constructor, that part is fine (see MDN, they use the same code in examples).
@MartinAdámek fair enough! Thanks for the correction.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.