Do you know why you cannot send files via $.post
? Maybe you don’t event know how you should start sending files? In this post you’re going to learn how to send files via ajax requests. I’m not going to show you how to implement server-side code, it’s up to you.
Preparation
Let’s start by preparing simple HTML form:
|
|
There is one point which should be noted. I’ve set the enctype
attribute to multipart/form-data
. It is required when you send files via regular forms, but since this will be sent via ajax it’s not needed. I’ve left it as a fallback.
Make sure that your page also includes jQuery script. We’ll also write some JavaScript code, so we need a place to put it.
If you already have server-side app ready, then you can test file upload. It works, but the files will be sent in a non-ajax way.
Ajax file upload
In it’s current state the form behaves in a regular way (post and reload). Right now we have to override submit button handler so form won’t be sent:
|
|
Next, we have to preparete form fields (in this case only the file) for sending. For this we’ll use FormData
, which will construct a data structure representing our form fields. Big advantage of FormData
is that it can be easily sent via ajax.
|
|
In the last step we’ll send the data. For this we need to determine the url which will handle our request. We’ll take it from form action
attribute. Then we set a couple of options for $.ajax
.
|
|
Why $.post won't work
Sometimes it happens that someone tries to send files using $.post
instead of $.ajax
. This won’t work and they don’t know why. Let me exaplain why.
First things first, $.post
is just a shorthand method, which under the hood uses $.ajax
. Basically $.post
sets parameters and executes $.ajax
. It makes code more readable and shorter. Here’s an example:
|
|
Secondly, it is impossible to set some of the parameters which have to be changed when using $.post
(for example processData
). For this reason the request uses default settings values. When you want to change them you have to use $.ajax
.
Lastly, the default settings values are inappropriate for sending files.
Default value for processData
setting is true.
It processes the data in such a way that it will fit default content-type (application/x-www-form-urlencoded
). Since we’re sending files, we don’t want that, so we set it to false
.
Then we have contentType
setting, which has a default value set to application/x-www-form-urlencoded; charset=UTF-8
. When we set it to false
content-type will be set to multipart/form-data
, which is required when sending files.
Handling the request
Once the file is uploaded you’ll probably want to perform some kind of action. You can that by assigning callbacks to $.ajax
using any of four available methods. Let’s see how it looks like:
|
|
A really quick summary of these four methods is as follows:
done()
– use when the request was successfullfail()
– when the request was unsuccessfullalways()
– use regardless of success or failurethen()
– a shorthand which allows passing done and fail callbacks
For more throughout explanation of $.ajax
and the callbacks listed above please refer to jQuery.ajax documentation.