Question
How to Upload Files Asynchronously with jQuery and FormData
Question
I want to upload a file asynchronously using jQuery.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<span>File</span>
<input type="file" id="file" name="file" size="10" />
<input id="uploadbutton" type="button" value="Upload" />
$(document).ready(function () {
$("#uploadbutton").click(function () {
var filename = $("#file").val();
$.ajax({
type: "POST",
url: "addFile.do",
enctype: "multipart/form-data",
data: {
file: filename
},
success: function () {
alert("Data Uploaded");
}
});
});
});
Instead of uploading the actual file, only the filename is being sent. How can I correctly upload the file asynchronously with jQuery?
Short Answer
By the end of this page, you will understand why reading a file input with .val() only gives you the filename, how to send the real file using FormData, and which jQuery AJAX options are required to upload files correctly.
Concept
When working with file uploads in the browser, a file input does not expose the raw file contents through .val(). That method only returns a string representation of the selected file, usually the filename or a fake local path.
To upload the actual file, you need to access the file object from the input element:
$("#file")[0].files[0]
This gives you a File object provided by the browser. That object contains the real file data, along with metadata such as the file name, type, and size.
To send that file with AJAX, the standard approach is to use FormData. FormData creates a multipart form request in the same format a normal HTML form would use when uploading files.
With jQuery AJAX, two settings are especially important:
processData: falseprevents jQuery from trying to turn the data into a query string.contentType: falselets the browser automatically set the correctmultipart/form-databoundary.
Without these, the file upload usually fails or sends the wrong payload.
This matters in real applications because asynchronous uploads are common in:
- profile photo uploads
- document submission forms
- admin dashboards
- chat apps with attachments
- drag-and-drop upload tools
The key idea is simple: a filename is just text; a file upload requires the actual file object.
Mental Model
Think of a file input like a luggage tag.
.val()gives you the label on the suitcase.files[0]gives you the actual suitcase.FormDatais the shipping box used to send the suitcase to the server.
If you only send the label, the server learns the file name but never receives the file itself.
If you put the real file into FormData, the browser can package and send it properly.
Syntax and Examples
The core pattern for asynchronous file upload with jQuery is:
var file = $("#file")[0].files[0];
var formData = new FormData();
formData.append("file", file);
$.ajax({
url: "addFile.do",
type: "POST",
data: formData,
processData: false,
contentType: false,
success: function (response) {
console.log("Upload successful", response);
},
error: function () {
console.log("Upload failed");
}
});
A full beginner-friendly example:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<input type="file" id="file" name="file">
<button id="uploadbutton">Upload</button>
<script>
$(document).ready(function () {
$("#uploadbutton").click(function () {
var fileInput = $("#file")[0];
if (fileInput.files.length === 0) {
alert("Please select a file first.");
return;
}
var formData = new FormData();
formData.append("file", fileInput.files[0]);
$.ajax({
url: "addFile.do",
type: "POST",
data: formData,
processData: false,
contentType: false,
success: function () {
alert("File uploaded successfully.");
},
error: function () {
alert("Upload failed.");
}
});
});
});
</script>
What this example does
- Gets the real DOM file input using
$("#file")[0] - Checks whether the user selected a file
- Creates a
FormDataobject - Appends the selected file under the field name
file - Sends it with
$.ajax()using the correct options
The field name in formData.append("file", ...) should match what your server expects.
Step by Step Execution
Consider this example:
$("#uploadbutton").click(function () {
var fileInput = $("#file")[0];
if (fileInput.files.length === 0) {
alert("Please select a file first.");
return;
}
var formData = new FormData();
formData.append("file", fileInput.files[0]);
$.ajax({
url: "addFile.do",
type: "POST",
data: formData,
processData: false,
contentType: false
});
});
Here is what happens step by step:
- The user clicks the Upload button.
$("#file")[0]gets the actual DOM element for the file input.fileInput.filesis read.- This is a list of selected files.
- For a single file input, the first file is
files[0].
- The code checks
fileInput.files.length === 0.- If no file was selected, it shows an alert and stops.
new FormData()creates an empty multipart request body.formData.append("file", fileInput.files[0])adds the file to the request.- The key is
file. - The value is the actual selected file.
- The key is
$.ajax()sends the request.processData: falsestops jQuery from converting the data into a regular query string.contentType: falsetells the browser to set the correct multipart content type automatically.- The server receives the uploaded file in the
filefield.
If you used $("#file").val() instead, step 6 would append only a string, not the file data.
Real World Use Cases
Asynchronous file uploads are used in many real applications:
-
Profile image upload
- A user selects a new avatar and uploads it without reloading the page.
-
Document submission
- Users attach PDFs, resumes, or invoices in a form.
-
Messaging apps
- A file is uploaded in the background before sending a chat message.
-
Admin dashboards
- Staff upload CSV files, product images, or reports.
-
Content management systems
- Editors upload article images and media assets.
-
Support tools
- Customers attach screenshots or log files to bug reports.
In all of these cases, the browser must send the actual file binary data, not just the filename.
Real Codebase Usage
In real projects, developers usually wrap file uploads with a few practical patterns.
Validation before upload
Common checks include:
- file selected or not
- maximum file size
- allowed file types
- number of files allowed
Example:
var file = $("#file")[0].files[0];
if (!file) {
alert("Choose a file.");
return;
}
if (file.size > 2 * 1024 * 1024) {
alert("File is too large.");
return;
}
Guard clauses
Developers often exit early when input is invalid:
if (!file) return;
This keeps code readable.
Upload progress
Larger apps often show a progress bar using XMLHttpRequest progress events.
Error handling
Production code usually handles:
- network failure
- server-side validation errors
- unsupported file types
- authentication problems
Sending extra fields with the file
FormData can include regular form values too:
var formData = new FormData();
formData.append("file", file);
formData.append("userId", 123);
formData.append("description", "Profile photo");
Multiple file uploads
If the input allows multiple files, developers loop over the files list and append each one.
These patterns make file uploads more robust and user-friendly.
Common Mistakes
1. Using .val() instead of the file object
This is the main issue in your original code.
Broken:
var filename = $("#file").val();
data: {
file: filename
}
Why it fails:
.val()returns text, not file content.- The server receives only the filename string.
Correct:
var file = $("#file")[0].files[0];
var formData = new FormData();
formData.append("file", file);
2. Forgetting processData: false
Broken:
$.ajax({
url: "addFile.do",
type: "POST",
data: formData
});
Why it fails:
- jQuery may try to serialize the data incorrectly.
Correct:
processData: false
3. Forgetting contentType: false
Broken:
$.ajax({
url: "addFile.do",
type: "POST",
data: formData,
processData: false
});
Why it fails:
- The browser needs to set the multipart boundary automatically.
Correct:
contentType: false
4. Setting enctype in the AJAX options and expecting it to work
This is a common misunderstanding.
enctype: "multipart/form-data"
Why it is misleading:
enctypeis normally used on an HTML<form>element.- In jQuery AJAX uploads,
FormDatapluscontentType: falseis what matters.
5. Not checking whether a file was selected
Broken:
var file = $("#file")[0].files[0];
formData.append("file", file);
If no file is selected, file is undefined.
Better:
if ($("#file")[0].files.length === 0) {
alert("Please select a file.");
return;
}
6. Mismatching the field name expected by the server
If the server expects upload, but you send file, the backend may not find the uploaded data.
formData.append("file", file);
Always match the backend field name exactly.
Comparisons
| Approach | What it sends | Good for file upload? | Notes |
|---|---|---|---|
$("#file").val() | Filename as text | No | Only gives the selected file name/path string |
data: { file: ... } | Regular form fields | No | Works for text values, not binary file data |
FormData + files[0] | Actual file contents | Yes | Standard browser approach |
| Normal HTML form submit | Actual file contents | Yes | Reloads the page unless handled differently |
val() vs files[0]
| Method | Returns | Use case |
|---|---|---|
$("#file").val() | String filename/path | Displaying the selected filename |
$("#file")[0].files[0] | File object | Uploading the real file |
Regular AJAX data vs FormData
| Type | Best for |
|---|---|
Plain object like { name: "A" } | Text fields and simple values |
FormData | Files and multipart form submissions |
Cheat Sheet
var fileInput = $("#file")[0];
var file = fileInput.files[0];
var formData = new FormData();
formData.append("file", file);
$.ajax({
url: "addFile.do",
type: "POST",
data: formData,
processData: false,
contentType: false,
success: function (response) {
console.log(response);
},
error: function () {
console.log("Upload failed");
}
});
Rules to remember
- Use
files[0], not.val(), to get the actual file. - Use
FormDatafor file uploads. - Always set:
processData: falsecontentType: false
- Check that a file is selected before uploading.
- Make sure the field name matches what the server expects.
Common edge cases
- No file selected
- File too large
- Wrong file type
- Backend expecting a different field name
- Multiple files requiring a loop
FAQ
Why does $("#file").val() only return the filename?
Because .val() reads the input's text value, not the file contents. For uploads, use $("#file")[0].files[0].
Do I need FormData to upload files with jQuery AJAX?
Yes, in modern browser-based AJAX uploads, FormData is the standard way to send files.
Why do I need processData: false and contentType: false?
They prevent jQuery from transforming the request incorrectly and allow the browser to create the proper multipart request.
Can I upload multiple files with this approach?
Yes. Use a file input with multiple and loop through input.files.
Can I send text fields together with the file?
Yes. Add them to the same FormData object using additional append() calls.
Is enctype: "multipart/form-data" enough in jQuery AJAX?
No. For AJAX file uploads, FormData and the correct jQuery options are what matter.
What should the server receive?
The server should receive a multipart form request with a file field whose name matches the key used in formData.append().
Mini Project
Description
Build a small asynchronous document uploader that lets a user choose a file, validates that a file was selected, and uploads it to the server without refreshing the page. This demonstrates the exact pattern used in many real applications such as profile uploads, admin tools, and support forms.
Goal
Create a working jQuery file upload flow that sends the actual file to the server using FormData.
Requirements
- Add a file input and an Upload button.
- Prevent upload if no file is selected.
- Use
FormDatato send the selected file. - Send the request with jQuery
$.ajax(). - Show a success or error message based on the result.
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.