I'm making a Javascript app for file uploading with Drag and Drop support - but I've hit a problem I've been stuck on for days.
It seems that 'dropped' files (in my case via jQuery, .on('drop', function(e){
) files aren't actually being sent.
I've been browsing answer after answer on StackOverflow - PLEASE DON'T MARK AS DUPLICATE. THE DUPLICATES DO NOT HELP - I'm yet to find an aspect which I have not considered in my implementation. It's as if this solution is working for everyone else but me...
Don't believe me? FIDDLE HERE
(Disclaimer: obviously I have modified my solution to not use cross-domain requests, I am using an endpoint I found on Fiddle as a substitute, but it appears to present the same problem I have been experiencing - hopefully it is sufficient as the basis for this example)
The issue is that the upload completes immediately - apparently it is only sending the text data and not uploading the file itself. Reviewing the request payload I see the data is not present.
Javascript
function uploadFile(file){
console.log("uploadFile");
var form = new FormData();
form.append('file', file);
form.append('hello', 'world');
$.ajax({
url: "/echo/js/?js=hello%20world!",
type: "POST",
data: form,
processData: false,
contentType: false,
cache: false,
success: function(data){
alert("SUCCESS");
}
});
}
$(document).ready(function(){
/* Disable default drag/drop browser behavior. */
$("html").on('drop', function(e){e.preventDefault(); e.stopPropagation();});
$("html").on('dragover', function(e){e.preventDefault(); e.stopPropagation();});
$("html").on('dragenter', function(e){e.preventDefault(); e.stopPropagation();});
$("html").on('dragleave', function(e){e.preventDefault(); e.stopPropagation();});
$(".drop_area").on('drop', function(e){
e.preventDefault();
e.stopPropagation();
var files = e.originalEvent.target.files || e.originalEvent.dataTransfer.files;
console.log(files);
for (var i = 0; i < files.length; i++) {
uploadFile(files[i])
}
});
});
HTML
<div class='drop_area'>
Drop your file in this div.
</div>
CSS
.drop_area {
border: 1px solid black;
background: #ffffff;
height: 300px;
width: 50%;
position: relative;
}
After seeing the blank request headers in Chrome, and based on the fast upload speed, I had assumed the files were not sending.
However after adding code to my backend endpoint (via var_dump($_FILES['file']);
), I see the following:
array(5) {
["name"]=>
string(14) "two-minute.mp4"
["type"]=>
string(9) "video/mp4"
["tmp_name"]=>
string(36) "/Applications/MAMP/tmp/php/phpXfCu0U"
["error"]=>
int(0)
["size"]=>
int(12904619)
}
The large size
attribute appears to indicate quite a lot of data was availible from my upload. It was probably working the whole time. I'll look at this more tomorrow but for the moment the answer may be that:
"It just looks like it's not working from your browser, but it actually is...".
Partial credit to @Alisher Gafurov for convincing me to double-check the backend implementation to verify if the file was indeed not present.