Submitting multipart/form-data using jQuery and Ajax

Error message

Deprecated function: Function create_function() is deprecated in GeSHi->_optimize_regexp_list_tokens_to_string() (line 4698 of /home/digipiph/public_html/sites/all/libraries/geshi/geshi.php).

It is possible to submit files using "multipart/form-data" and ajax. There are many sites out there that show complicated ways of doing this when it is really easy. It simply requires a little configuration of the jquery ajax process and grabbing your form data using the FormData() function.

Using the following method, you can submit multiple files and are not just limited to one.

Lets take a look at our form.

<form id="data">
  <input type="hidden" name="id" value="123" readonly="readonly">
  User Name: <input type="text" name="username" value=""><br />
  Profile Image: <input name="profileImg[]" type="file" /><br />
  Display Image: <input name="displayImg[]" type="file" /><br />
  <input type="submit" value="Submit">
</form>

The above form has a hidden field, a user name field, and then two file image fields that we are going to submit to our PHP processing page.

Now lets look at the jQuery used to submit the form using "multipart/form-data" and ajax.

//Program a custom submit function for the form
$("form#data").submit(function(event){
 
  //disable the default form submission
  event.preventDefault();
 
  //grab all form data  
  var formData = new FormData($(this)[0]);
 
  $.ajax({
    url: 'formprocessing.php',
    type: 'POST',
    data: formData,
    async: false,
    cache: false,
    contentType: false,
    processData: false,
    success: function (returndata) {
      alert(returndata);
    }
  });
 
  return false;
});

That is all that is needed to submit your "multipart/form-data" form to a PHP processing page using ajax. You would call your form data on the processing page like normal.

$id = $_POST['id'];
$username = $_POST['username'];
$profileImg = $_FILES['profileImg'];
$displayImg = $_FILES['displayImg'];

Comments

It works perfectly!

This was really helpful. Thank you for a short but complete explanation about it. 

Thank you, you make my day!

thank you so much may please know the meaning of this linesdata: formData,
async: false,
cache: false,
contentType: false,
processData: false, 

You should read up on the Jquery Ajax documentation.

I will elaborate on the two of the important ones for multi-part forms.

contentType and processData are needed when passing multi-part forms as when one sets the contentType option to false, it forces jQuery to remove the Content-Type header, otherwise, the boundary string will be missing from it. Also, when submitting files via multi-part/form one must leave the processData flag set to false, otherwise, jQuery will try to convert your FormData into a string, which will fail.

Sorry but it doesn't work with me !! the page not communicate with php page !!!!! i don't know why !!! i make the something of the code ! copy past !!

Hey Kamal, are you trying to pass the form data to a page on your same domain, different domain, or sub-domain?

What browser are you testing this in?

Do you have size restrictions on your server for $_POST variables?

hi thanks to reply to my messageno i'm working on localhost i use the last version of mozilla firefox as browserabout the variable $_POST it work successfuly no problem with it ! my jquery-ajax Code: <script type='text/javascript'>$(document).ready(function(){$('#form_photo').submit(function(event){    event.preventDefault();  var formData = new FormData($('#form_photo')[0]);  $.ajax(    {    url: 'addphoto.php',    type: 'POST',    data: formData,    async: false,    cache: false,    //dataType: 'json',    contentType: false,    processData: false,    success: function(returndata){    //alert(returndata);     $('#error').hide().append(returndata).slideDown();     }  });   return false;  });});</script>---------------------------------------------------------------------------------------------------------------------------------------------------------------html Code: <form enctype='multipart/form-data' id='form_photo' action='#' method='post'>                             <input type='hidden' name='id' value='".$ID."' readonly='readonly'>                    <input name='photo[]' type='file' style='width: 300px; '><br /><br />                    <input type='submit' value='Upload' id='submit_photo' style='color:red; font-weight:bold; padding:1px 5px; width: 100px; margin-left:100px;'><br/>    </form>   ---------------------------------------------------------------------------------------------------------------------------------------------------------------PHP code:<?php$id = $_POST['id'];$photo = $_FILES['photo'];echo $id;?> ---------------------------------------------------------------------------------------------------------------------------------------the result is all variable on PHP are empty !! can you help me please !

Hey Kamal,

Your script seems correct. I have a feeling it may be server restrictions. Could you provide a link to a demo page where you are trying to get this working? Are you getting any error messages in the console's error log?

 

It works like charm... :)

Thanks for the code is perfect!!!

Much love to you...script worked like a charm :-)

very nice tutorial

It Help me alotttttttttttttttt .... Thanks ....... 

very nice tutorial.. Thank you So much ... its very usefull for me.....

This is brilliant....... Thanks

Thank you veeeery much!It works and it's easy!

Worked. thanks a millons. :)

Thanks, this tutorial helped me! 

You helped me out. Thanks!!!But how can I reset the form after a succesful insert?

Hey Zitar, you could use the "reset" function during Ajax's success function.

Example:

  $.ajax({
    /* other junk here from above, cut out to save space */
    success: function (returndata) {
      //obviously change the #data to your form's id
      $("form#data")[0].reset();
    }
  });

Muy útil tu aporte, me ayudo muchísimo. Gracias.

IS there any way to prevent auto submit upon page load? additionally is there any way to pass a php variable through this? currently it's not letting me do anything but text 

Hey Rodney,

I'm not quite sure what you are doing as the code above only fires once the submit button for form id "data" is clicked.
If your form is auto submitting, check your code to see if you have any page load functions triggering your form to submit.

If you have a PHP variable that you want your form to submit, you can add another field to hold that variable.

Example:

<form id="data">
  <input type="hidden" name="phpVar1" value="<?=$somephpvariable?>" readonly="readonly">
  <input type="hidden" name="phpVar2" value="<?=$someotherphpvariable?>" readonly="readonly">
  <input type="hidden" name="id" value="123" readonly="readonly">
  User Name: <input type="text" name="username" value=""><br />
  Profile Image: <input name="profileImg[]" type="file" /><br />
  Display Image: <input name="displayImg[]" type="file" /><br />
  <input type="submit" value="Submit">
</form>

If you didn't want to pass the PHP variables via the form, then you should look into $_SESSION variables.

Hey thanks a lot for your code... i want ask you how about submit two form or more? 

You could submit any number of forms simply by calling the object with jQuery and then using the submit function. So, if you wanted to automatically submit another form after the first one has completed, add the jQuery submit() trigger to the Ajax success function, like so:

$("form#data").submit(function(event){
 
  ...
 
  $.ajax({
    ...
    success: function (returndata) {
      //after ajax returned successful, submit form id "data2", then "data3"
      $("form#data2").submit();
      $("form#data3").submit();
    }
  });
 
  return false;
});

After my original form was submitted, I then submit forms "data2" and "data3". You would probably want to create custom form handlers for those forms like you did for form id "data" in my example above.

Thank you, this code woks fine for me.

This code a life saver

How do refresh the image content when succesfully uploaded without page reload?

If you already have an image on the page that your form is updating, you would call the object by its ID and change its source with the uploaded image's source.

  <img id="profileImage" src="images/user/profile.jpg">
  $.ajax({
    /* other junk here from above, cut out to save space */
    success: function (returnImgSrc) {
      $('#profileImage').attr('src', 'images/user/'+returnImgSrc);
    }
  });

You would need to have your PHP processing page ONLY return the new image's path.

  //return the path and image name
  echo 'newprofilepic.jpg';

I personally like to return errors if they should exists to my ajax function. I personally would go about it like this.

  $.ajax({
    /* other junk here from above, cut out to save space */
    success: function (returnData) {
      if (returnData) {
        //alert user to uploading error
        alert('Error: '+returnData);
      }
      else {
        //no error, call function to load uploaded image
        updateImage();
      }
    }
  });
 
  function updateImage() {
    //use ajax to query the new image's link and return it
    $.ajax({
      /* other junk here from above, cut out to save space */
      success: function (returnImgSrc) {      
        //on success, update your image's src
        $('#profileImage').attr('src', 'images/user/'+returnImgSrc);
      }
    });
  }

If you need help with processing uploaded files/images, I would suggest checking out my other post, Simple PHP Class used for uploading files and images.

You Save me!!! Thank you very much!!

Thanks you, I've been hitting a brick wll with this and just wanted a simple concise solution - this is perfect!

Thanks so much for your extreeeemly simplifed functional code. How do I submit along with this form, extra input field data not located on the form?Please help with the code snippet. Thank you.

The following should do the trick.

//grab all form data  
var formData = new FormData($(this)[0]);
 
//add other inputs to formData
//formData.append("key", "value")
 
formData.append("other-input-id", $("#other-input-id").val());

You're the guru, man. It works exactly like magic !!!Thanks sooooooooo much. My headache is gone......

How to insert $profileImg into the table? Will it store just the link or actual file?

You can have the database store the path to the uploaded file OR you can have the database store the actual file itself as BLOB type.

I would personally store the uploaded file in a directory opposed to in the database itself, but if you insist on storing the file in the database, you would do something like the following:

$imageName = $profileImg["name"];
$imageData = file_get_contents($profileImg["tmp_name"]);
 
$sth = $pdo->prepare('INSERT INTO image (name,image) VALUES (:name,:image)');
$sth->bindParam(':name', $imageName, PDO::PARAM_STR);
$sth->bindParam(':image', $imageData, PDO::PARAM_LOB);
$sth->execute();

your code seems to be great, but still dont work for me:i try to make search for google marker, so it works when i write this:<code> $search = 'TP164';<code>but doesnt work if i try to get from form: $search = $_POST["username"];</code> 

hi, the code worked but i didnt get a success message 

Hey Victor, you will need to make one by either changing the alert in the success of $.ajax to something like:

$.ajax({
    ...
    success: function () {
      alert("Upload Complete");
    }
    ...

Or, if you wanted to return a message from your processing page, you will need to have your form processing page return a value by using echo or print.

//formprocessing.php
 
echo 'This page received:';
print_r($_POST);
$.ajax({
    ...
    success: function (returnedData) {
      alert(returnedData);
    }
    ...

I've searched hours and hours for this.. love you! haha thanks

Thank you for sharing this, it worked easily.;)

hi, great code ,  i would like to log the contents of formDatajust after thevar formData = new FormData($('#form_artwork')[0]);            // log contents                    console.log(formData);but of course this code doesn't worki tried fomData[0] but return is undefined could you help me thanks

Unfortunately you can't, see Mozilla's documentaion on "Using FormData Objects". You can only use them for building FormData to send via an AJAX request.

Some people posted some work arounds by building their own object. If you would like to try some of those on Stack Overflow.

thank you to sharing this wonderful code sir, its working nice

I have tried this code to submit a multipart form, in mozilla ,it always returns a response as undefined and data  not submitted.

Thanks a lot Sir! Works great!

Thanks a lot!

hi, thank you for this peace of code, it helped me a lot in my project, it is simple and straight to the point and it's working.

The code works fine but I want to save the name of the file uploaded by the user and not not just BLOB[size]. and also I want the image to be loaded in some folder using move_upload_image(). Thanks.

Pages