Sending FormData with jQuery.ajax()

This post explains how you can send the HTML5 FormData object as an AJAX request with jQuery. If you’re simply looking to learn how you can submit a form via AJAX using jQuery please checkout my other blog post instead; Submitting a form as an AJAX request using jQuery.

HTML5 introduces FormData to allow developers to build forms objects dynamically (and can even include files from the user’s file system), and then to send this form object via AJAX. You can easily use FormData with an XMLHttpRequest by passing the FormData instance as the parameter to xhr.send(). However, what if you want to send the FormData using jQuery?

Unfortunately, it’s not as easy as setting the data attribute to the FormData instance; jQuery runs anything that isn’t a string through jQuery.param() to serialize the objects keys into key1=a&key2=b etc; running FormData through this doesn’t end too nicely.

However one of jQuery.ajax()‘s many options is processData, which allows you to turn off this behaviour by setting it’s value to false. So, to use FormData with jQuery.ajax() it’s as simple as:

var formData = new FormData($('form')[0]); // Create an arbitrary FormData instance

jQuery.ajax('/endpoint.php', {
    processData: false,
    contentType: false,
    data: formData

Note we’ve also had to set contentType to false as well; unless contentType is specified as an option to jQuery.ajax(), jQuery reverts to the default of "application/x-www-form-urlencoded". By setting contentType to false we prevent this option from being set, and the browser implementation of XMLHttpRequest (which jQuery uses behind the scenes of course) will set the correct Content-Type header for us.

Be aware that no amounts of jQuery will make FormData cross browser. Whilst most browsers have supported FormData since the stone age (Chrome 7, Firefox 4.0 and Safari 5), Internet Explorer and Opera are the noticeable exceptions, with support only being added in Internet Explorer 10 and Opera 12 respectively. As there’s no real polyfill/ fallback you can employ for FormData, you should use feature detection and degrade gracefully as appropriate.

if (!("FormData" in window)) {
    // FormData is not supported; degrade gracefully/ alert the user as appropiate

20 thoughts on “Sending FormData with jQuery.ajax()

  1. Hi, Tried your code. and I get error at

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

    Dont we have to use #form in FormData?

  2. Hi Shaz,

    I’m expecting you to replace the literal `’form’` with a selector to target your form. If your form has an ID of `form`, then you’re right in saying that using `#form` will do the trick!

  3. Hello.

    Thanks for the tutorial, it was very helpful.

    Here I leave other ways can do.

    var formData = new FormData(document.forms.namedItem("uploadForm"));
    var formData = new FormData(document.getElementById("uploadForm"));

    Best Regards!

  4. is there any way other than using FormData for uploading some file? As I am using browser which has HTML 4 that doesn’t support FormData 🙁

  5. @Rowen: There’s plenty of other ways, however they’re all a bit hacky. For instance, you can use a hidden iframe, and use that to upload your files. You can also revert to flash if you wanted.

    One technique you can apply is to use progressive enhancement; detect whether your users are using a HTML5 supported browser, and use FormData, and if not fall back to one of the above methods.

  6. awesome..helped me a lot!!..i am trying to send the file one by one to my php script..but there is no response..can you help with the php???

  7. If a page has a file type and other field type how do we serialize? In general I am serializing the form for fields like radio, select, checkbox by using var str = $("form").serialize(); ,
    and if there is a filetype seperatly then I am using jQuery("input[type=file]").change(function() {var fd = new FormData($('#formid')[0]);

    How can we serialize the data if the page has a file type and other field type?

Leave a Reply

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