Have you ever uploaded a resume, profile picture, assignment, or PDF to a website?
You choose a file, click Upload, and after a few seconds you see:
✅ Upload successful!
It looks simple from the user's side.
But behind that simple button, the browser, backend, file storage, and database are working together.
So what actually happens when you upload a file?
Let's understand it using a simple example: uploading a resume.pdf to a job website.
The Big Picture
The basic flow looks like this:
Select File
↓
Browser
↓
FormData
↓
HTTP POST Request
↓
Backend
↓
Validate File
↓
Store File
↓
Save File Information
↓
HTTP Response
↓
Upload Complete
Let's understand each step.
1. You Select the File
Suppose a job website asks you to upload your resume.
You select:
resume.pdf
The browser gives JavaScript a File object representing the selected file.
For example:
const file = fileInput.files[0];
console.log(file.name);
console.log(file.size);
console.log(file.type);
You might get:
resume.pdf
245000
application/pdf
A File object is simply JavaScript's representation of the file selected by the user.
At this point, the file has only been selected. It hasn't been uploaded yet.
2. The File Is Put Into FormData
Now we need to prepare the file to send to the backend.
This is where FormData is useful.
Think of FormData like a package containing the information we want to send.
const formData = new FormData();
formData.append("file", file);
formData.append("userId", "42");
Our package now contains:
file → resume.pdf
userId → 42
So FormData helps us package the file and other form information before sending it.
3. The Browser Sends an HTTP Request
Now JavaScript sends the FormData to the backend.
For example:
fetch("/api/upload", {
method: "POST",
body: formData
});
The browser sends a POST request to:
/api/upload
The file is sent using a format called:
multipart/form-data
4. What Is multipart/form-data?
Normally, an HTTP request might contain simple information like:
name = Darshan
email = darshan@example.com
But a file upload contains actual file data along with other fields.
multipart/form-data allows different pieces of data to be sent together in one HTTP request.
For example:
HTTP Request
userId → 42
file → resume.pdf
So remember:
multipart/form-data is a format used to send files and other form data together in an HTTP request.
5. The Backend Receives the File
The request now reaches the backend.
For example, in a Node.js and Express application, a library such as Multer can process the uploaded file.
A simplified example looks like this:
app.post("/api/upload", upload.single("file"), (req, res) => {
console.log(req.file);
});
The backend can now access information about the uploaded file.
For example:
filename → resume.pdf
size → 245 KB
type → application/pdf
But the backend shouldn't immediately trust the file.
It should validate it first.
6. The Backend Validates the File
The backend should never blindly trust files coming from the browser.
For example, our job website might allow:
PDF
DOCX
But someone might try to upload:
virus.exe
The backend should reject it.
It can check things such as:
- File type
- File size
- File name
- Other application-specific rules
For example:
resume.pdf
Size: 2 MB
Type: PDF
↓
✅ Valid → Continue
But:
resume.exe
↓
❌ File type not allowed
File size limits are also important.
For example:
Maximum allowed size: 5 MB
resume.pdf → 2 MB
↓
✅
But:
large-video.mp4 → 500 MB
↓
❌
So:
The backend validates the file before processing or storing it.
7. Where Is the Actual File Stored?
After validation, the application needs to store the actual file.
There are different ways to do this.
For example:
- Local server storage
- Cloud/object storage
For many modern applications, files such as images, videos, and PDFs are stored in object storage.
The simplified flow is:
resume.pdf
↓
Backend
↓
File/Object Storage
↓
Actual file stored
The important point is that the actual file and its information don't necessarily need to be stored in the same place.
8. What Does the Database Store?
A common beginner question is:
"If the PDF isn't stored directly in the database, how does the application know where it is?"
The database can store metadata about the file.
For example:
files table
id → 101
user_id → 42
filename → resume.pdf
size → 2 MB
file_url → /uploads/resume.pdf
uploaded_at → ...
So we can think of it like this:
Actual file
↓
File/Object Storage
File information
↓
Database
The database stores information that helps the application manage and find the file.
9. The Server Sends a Response
Once the file has been successfully stored and the required information has been saved, the backend sends a response to the browser.
For example:
HTTP/1.1 201 Created
The response might contain:
{
"message": "File uploaded successfully",
"fileUrl": "/uploads/resume.pdf"
}
The browser receives the response.
The website can now show:
✅ Resume uploaded successfully!
That's when the user knows the upload is complete.
10. What If Something Goes Wrong?
Uploads don't always succeed.
For example, imagine you upload a 15 MB file while the website allows only 5 MB.
The process might look like:
resume.pdf
↓
File size = 15 MB
↓
Maximum allowed = 5 MB
↓
❌ Upload rejected
The backend might send:
{
"message": "File size exceeds the limit"
}
The frontend can then show:
❌ Upload failed: File is too large.
The same idea applies if:
- The file type isn't allowed.
- The request is invalid.
- Storage fails.
- The server encounters an error.
So the browser needs to handle both success and failure responses.
The Complete File Upload Journey
Let's put everything together.
Imagine you upload:
resume.pdf
The complete journey is:
User selects resume.pdf
↓
Browser creates File object
↓
File added to FormData
↓
POST /api/upload
↓
multipart/form-data
↓
Backend receives file
↓
Backend validates file
↓
Actual file stored
↓
File metadata saved in database
↓
Backend sends response
↓
Browser shows upload result
In a real application, the architecture might look like:
Browser
│
│ POST /api/upload
↓
Backend API
│
┌──────┴──────┐
↓ ↓
File Storage Database
actual file metadata
│ │
└──────┬──────┘
↓
Response
↓
Browser
A Simple Mental Model
You don't need to memorize every technical term.
Just remember this:
I select a file → the browser creates a File object → puts it into FormData → sends it using an HTTP request → the backend receives and validates it → the actual file is stored → file information is saved in the database → the server sends a response → the browser shows the result.
Or simply:
Select
↓
Package
↓
Send
↓
Validate
↓
Store
↓
Save Metadata
↓
Respond
Final Takeaway
A file upload may look like a single action to the user:
Choose File → Upload
But behind that simple button, several components work together:
Browser
↓
HTTP
↓
Backend
↓
File Storage
↓
Database
↓
Response
The browser handles the file selection and sends the request.
The backend validates and processes the file.
The actual file can be stored in file/object storage, while the database can store information about that file.
Finally, the backend tells the browser whether the upload succeeded or failed.
The next time you upload a resume, profile picture, or assignment, remember that there's a lot happening behind that simple Upload button.
And that's the basic idea of how file uploads work on the web.
Thanks for reading!
If you're learning web development, don't just use the Upload button.
Try to understand what happens behind it.
Top comments (0)