1

I'm trying to implement a HTML5 ajax file upload with the help of HTML5's File API. It is based on Afzaal Ahmad Zeeshan's answer to this question.

My main aim would be to be able to let users upload .xls and .xlsx spreadsheet for later use.

HTML

<form class="form-uploadXLS" method="post" action="php/uploadXLS.php" enctype="multipart/form-data">
    <div class="form-group">
        <div class="col-md-12">
            <input type="file" name="xls" class="xls" />
        </div>
    </div>
    <input type="button" value="Upload" class="btn-uploadXLS" />
</form>
<progress></progress>

And here are the jQuery event handlers, just like in the above mentioned answer:

File input onChange event:

$('.xls').on('change', function () {
    var file = this.files[0];
    var fileName = file.name;
    var fileType = file.type;
    var fileSize = file.size;

    console.log("file name: " + fileName + ", type: " + fileType + ", size: " + fileSize);
});

This works correctly, the file's name, type and size gets logged to the server.

Upload button's onClick event:

$('.btn-uploadXLS').on('click', function (event) {
    event.preventDefault();
    console.log("Upload button clicked");
    var formData = new FormData($('.form-uploadXLS')[0]);

    $.ajax({
        url: 'php/uploadXLS.php', //Server script to process data
        type: 'POST',
        xhr: function () { // Custom XMLHttpRequest
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) { // Check if upload property exists
                myXhr.upload.addEventListener('progress', progressHandlingFunction, false); // For handling the progress of the upload
            }
            return myXhr;
        },
        //Ajax events
        beforeSend: function (stuff) {
            console.log("BeforeSend");
            console.log(stuff);
        },
        success: function (data) {
            console.log("Success!");
            console.log(data);
        },
        error: function (error) {
            console.log("Error!");
            console.log(error);
        },
        // Form data
        data: formData,
        //Options to tell jQuery not to process data or worry about content-type.
        cache: false,
        contentType: false,
        processData: false
    });
});

On server side, I'm using this PHP code to check if the file has been sent to the server

if(!empty($_FILES['xls'])) {
    echo '<pre>',print_r($_FILES,1),'</pre>';
}
else {
    die('no $_FILES variable');
}

And here's the result of print_r:

Array
(
[xls] => Array
(
[name] =>
[type] =>
[tmp_name] =>
[error] => 4
[size] => 0
)

)

According to the documentation, error code 4 means: UPLOAD_ERR_NO_FILE Value: 4; No file was uploaded.

What am I doing wrong?

Edit:

If I disable the click event listener and submit the form as normal, the file gets uploaded without problems.

I've noticed, that the formData variable doesn't have any value. This is the value of formData after it's been set: FormData { append=append()}

14
  • Yes using ajax u can not directly send the files. check this link you need to get the file data in a separate var and then append stackoverflow.com/questions/20097081/php-ajax-file-upload-error Commented Mar 6, 2014 at 21:00
  • 1
    @AbhikChakraborty he is already doing it properly. There's nothing wrong with how he is sending the files via ajax. Commented Mar 6, 2014 at 21:03
  • Have you tried different files? different browsers? Have you tried disabling the button click handling and instead having it submit the form to see if it works without ajax (for debugging)? Commented Mar 6, 2014 at 21:04
  • 1
    The only thing i see you doing differently than many other examples is you're passing the entire form to FormData rather than just adding the file to it. However, looking at documentation, the form should be enough. Commented Mar 6, 2014 at 21:21
  • 1
    Try changing the input name to name="xls[]" - eh... nevermind, that's only for when you're allowing the selection of multiple files for upload. Commented Mar 6, 2014 at 21:28

2 Answers 2

0

For some reason the problem was with the formData variable, previously defined as such:

var formData = new FormData($('.form-uploadXLS')[0]);

I've changed the index to 1 like this..

var formData = new FormData($('.form-uploadXLS')[1]);

.. and for some reason it works now.

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

Comments

-1

Instead of:

if(!empty($_FILES['xls'])) {

try this:

if(!empty($_FILES['xls']['name'])) {

type = $_FILES['xls']['type']) tmp = $_FILES['xls']['tmp_name'])

1 Comment

Well since the $_FILES['xls'] in fact doesn't have a file (as you can guess by error code 4), using this technique leads to die('no $_FILES variable');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.