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
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>
Upload
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.
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:
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:
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]
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: false
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.
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
Adding Table Rows with jQuery: append(), Limits, and Best Practices
Learn how to add table rows in jQuery using append(), what elements are allowed in tables, and safer ways to build rows dynamically.
Bower vs npm: What’s the Difference in JavaScript Package Management?
Learn the plain difference between Bower and npm, how each manages packages, and why npm replaced Bower in most JavaScript projects.
Can `(a == 1 && a == 2 && a == 3)` Ever Be True in JavaScript?
Learn how JavaScript type coercion, loose equality, and custom object conversion can make `a == 1 && a == 2 && a == 3` true.