phpjqueryhttpjqueryform

jqueryForm and empty uploads


Been scratching my head for too long on this: Using jquery.form, (http://malsup.com/jquery/form) with PHP ... my $_FILES['someimage'] gets set but the error number is always UPLOAD_ERR_NO_FILE, size is also 0.

The JavaScript:

$('form input[type=file]').change(function () {
    $(this).clone().appendTo('#imgform');
    $('#imgform').ajaxForm();
    $('#imgform').ajaxSubmit({
        type: 'POST'
    });
});

Which appends to:

<form id="imgform" method="POST" action="/api/images.php" enctype="multipart/form-data"></form>

From another form which has bog-standard file inputs.

PHP logs are clean, but var_dumping $_FILES always shows that the index is set to the name of the form element ... but no data.

Thanks guys! (Sorry, I know jQuery-like questions are too frequent round these parts).

EDIT I found Clone a file input element in Javascript which contains further information and suggested alternatives.

What I decided to do is have a single form for non JavaScript browsers, and JavaScript/jQuery breaks the single form into three forms:

Head form -> File upload form -> tail form

Then I can post the file upload async, and when the tail's submit is clicked, glue the form together into a POST as they are just text fields.


Solution

  • Two things I see when I try to run this. Since you are cloning then appending, I wonder if your file input exists within the context of the form. If not, then $('form input[type=file]') will never find the element to be cloned.

    Perhaps the biggest problem, though, is in the way browsers handle file upload controls. You cannot programmatically set a value on a file input control - otherwise it would be trivial as a web developer to automatically set the file upload value to "c:\Files\MyPasswordFile.txt" and automatically submit the form invisibly to the user.

    When I changed your code to this:

    <input type="file" name="imageFile" />
    <form id="imgform" method="POST" action="/api/images.php" enctype="multipart/form-data">
    
    </form>
    
    <script>
      $('input[type=file]').change(function() {
        alert("ACTION");
        $(this).clone().appendTo('#imgform');
        //$('#imgform').ajaxForm();
        //$('#imgform').ajaxSubmit(
        //        {
        //          type: 'POST'
        //        }
        //    );
      }); 
    </script>
    

    I can see the behavior as above - the field is cloned and appended - but it has no value. Since part of the clone process involves setting the field value - this would violate that security restriction and thus fails.