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.
$.ajax({ 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.
Note – depending 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.