Submit file input via AJAX with jQuery the easy way

Learn how to submit File input through an AJAX webform the easy way.

You make a webform that you’d like to be hipster about and submit by AJAX. jQuery makes this a breeze so there’s no problem. You probably use serialize() to encode the form data, and all is well.

But then you want to include a file input field with the form submission and your remote AJAX handler doesn’t receive it at all. Well, serialize() says that it doesn’t serialize form data so now what?

The answer is the FormData object. The FormData object lets you compile a set of key/value pairs (including File input) to send using XMLHttpRequest (an AJAX call) and the transmitted data is in the same format that the form’s submit method would use to send the data if the form’s encoding type were set to multipart/form-data.

And now to tie things together, an example of submitting an AJAX webform with jQuery. Note how the FormData object is used to “serialize” the form and how jQuery is set to not process the data nor set the content type.

$( '#my-form' )
  .submit( function( e ) {
    $.ajax( {
      url: 'http://host.com/action/',
      type: 'POST',
      data: new FormData( this ),
      processData: false,
      contentType: false
    } );
    e.preventDefault();
  } );

34 thoughts on “Submit file input via AJAX with jQuery the easy way

  1. I have tried to do same but it did not work for me, $_POST & $_FILES both are empty on script page. Please help me to solve this it is very urgent.
    Here is my code :

    ajax :

    //data = $(“#reply-form”).serialize();

    data = new FormData($(“#reply-form”));

    $.ajax({

    ‘url’ : “{{URL::route(‘addEmailRequest’)}}”,

    ‘type’ : ‘post’,

    ‘data’ : data,

    processData: false,

    contentType: false,

    beforeSend: function(XHR){

    $(‘.loading’).show();

    }

    })

  2. I have got the solution for that…………
    Just change

    data = new FormData($(“form-id”));

    to

    data = new FormData($(“form-id”)[0]);

  3. Thank you. This is nice.
    However the code throws error at data = new FormData($(“form-id”)[0]); when you have “use strict”; set.

  4. I am tearing my hair out on this one. I have tried seven ways to Sunday to get this working on a project I am on and finally broke it into a simple test, which failed. The Ajax is called, but the PHP seems to receive empty POST data. I tried dumping the POST data with print_r and it comes up empty. My JQuery looks like:

    $( ‘#newsForm’ )

    .submit( function( e ) {

    var myData = new FormData($(“#newsForm”)[0]);

    if (!(“FormData” in window)) {

    console.log(‘FormData not supported.’);

    }

    $.ajax( {

    url: ‘ajaxEditNewsItem.php’,

    type: ‘POST’,

    data: myData,

    cache: false,

    processData: false,

    contentType: ‘undefined’

    } );

    e.preventDefault();

    } );

    My HTML looks like:

    日数後表示

    登録クリア

    Any ideas?

      • That should be empty since I don’t have a file element. I had one in my original form, but simplified it to a 1-input form without a file to see if it would work for the simplest scenario and it bombed.

    • I’ve just noticed that in your simplified test your input field doesn’t have a name attribute. I don’t know if the HTTP spec says to ommit those fields from the request altogether (it might be available as raw data) but without a name I’m certain that it won’t show up in the $_POST variable. You need name as the data key.

      • Thanks! I added in the name attribute and now see the elements coming up in the request payload(in Chrome). I still get nothing form $_POST at the other end, though. print_r($_POST) dumps an empty array. I remember in the past when doing POST that I had to set the content-type, but we’re supposed to make it false, correct?

        • Well in the request headers, what does Chrome say that the request type is? Without a file payload or an explicit type, it might default to GET. If you send a file however, it will certainly be POST as you can’t send multipart data via GET as far as I know.

          • Request type is POST and it gets a 200 status back. Some other info back:
            Connection:
            Keep-Alive
            Content-Type:
            text/html
            Date:
            Mon, 25 May 2015 19:35:14 GMT
            Keep-Alive:
            timeout=5, max=72
            Server:
            Apache
            Transfer-Encoding:
            chunked
            Accept:
            */*
            Accept-Encoding:
            gzip, deflate
            Accept-Language:
            en-US,en;q=0.8,ja;q=0.6
            Connection:
            keep-alive
            Content-Length:
            241
            Content-Type:
            undefined
            User-Agent:
            Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Safari/537.36
            X-Requested-With:
            XMLHttpRequest

            The request payload(I added another variable called daysbefore) looks like:
            ——WebKitFormBoundaryPpAxbJg1jlba2pW9
            Content-Disposition: form-data; name=”daysbefore”

            11
            ——WebKitFormBoundaryPpAxbJg1jlba2pW9
            Content-Disposition: form-data; name=”daysafter”

            22
            ——WebKitFormBoundaryPpAxbJg1jlba2pW9–

          • Hold the phone! Your suggestion of adding the name attribute solved the problem. I had tweaked one other thing in searching for an answer and hadn’t un-tweaked it when I added in the name attrib. After returning that to the way it had been, all is working. Thank you!

  5. where is the wrong thing it’s 3 hours trying to fix the problem and your solution is the most close one

    $( “#orders” ).submit(function( event ) {
    /* alert( “Handler for .submit() called.” );*/
    event.preventDefault();

    /*$.ajax( {
    data: new FormData( this ),
    processData: false,
    contentType: false
    } );*/

    var url = $(this).attr(‘action’);
    // var postData = $(this).serialize();
    var postData = new FormData( this );

    $.post(url, postData, function(o){
    if (o.result == 1) {
    $(“#register_form_error”).show();
    var output = ‘Order Added Successfuly‘;
    $(“#register_form_error”).html(output);
    $(“.success_story”).hide();
    $(“.hidden”).show();
    } else {
    $(“#register_form_error”).show();
    var output = ”;
    for (var key in o.error) {
    var value = o.error[key];
    output += ‘Error :‘ + value +”;
    }
    $(“#register_form_error”).html(output);
    }
    }, ‘json’);

  6. You can upload data and files with one form using ajax.

    js:–>

    //Ajax
    $(“form#data”).submit(function () {
    var formData = new FormData($(this)[0]);
    $.ajax({
    type: “POST”,
    url: base_url + ‘commencement/get_details’,
    type: ‘POST’,
    data: formData,
    success: function (response) {
    console.log(response);
    },
    cache: false,
    contentType: false,
    processData: false
    });

    html like: —>

    Submit

Leave a Reply

Your email address will not be published. Required fields are marked *


*