How To Send Images And Other Files Using AJAX In jQuery


You must have been using AJAX via jQuery for tasks such as sending form data, background commands etc. There is however one thing almost everyone get stuck at least once – sending a file using jQuery AJAX. You you have a form with a simple file type input tag and you tried saving it’s content using, say PHP on server-side, you’ll find that the file input was simply not transmitted and you probably got a ‘undefined index’ error.

Let’s first see why it doesn’t work. By default when you pass something in the ‘data’ parameter, jQuery converts it into a query string of the type specified by the ‘contentType’ parameter. If this parameter is not specified then the default value of ‘application/x-www-form-urlencoded; charset=UTF-8‘ is used. This conversion clearly supports only text data and hence any file type input is simple discarded.

The solution is simple, as specified in the example provided below.

    type: "POST",
    processData: false,
    contentType: false,
    url: "url_to_server-side_file",
    data: new FormData($('form_selector')[0]),
    success: function(msg){
        //do something;

Lets see whats happening here.

  • By specifying ‘processData‘ to false we prevent any conversion of passed data into a query string.
  • Specifying ‘contentType‘ to false prevents jQuery from setting any content type headers.
  • new FormData creates a FormData object containing data of all fields in the selected form. Here ‘form_selector‘ is any arbitrary jQuery selector to your form. For example is the id of your form is ‘form1’ then it will be ‘#form1’.

After this you can receive the file on server-side like it would have been passed normally.

Notedepending on your server’s configuration, you may not be able to send large files using this as there is a size limit of POST and GET messages. POST is the recommended method for sending files as it is less dependent on the client. You may find a setting having name similar to ‘post_max_size’ in your server’s .htaccess file. You can set it to, say 100M, 200M etc. For more information see here and here.