Understanding multipart/form-data: How to Send Files and Text in a Single Request

Author

Tekrunner

Published

20 Jan, 2026

Understanding multipart/form-data: How to Send Files and Text in a Single Request

There’s a concept every backend developer eventually runs into when dealing with forms that go beyond simple text. It usually sounds like this: “How do I send both text and files in the same request?”
The answer lies in something called multipart/form-data, and understanding it properly can save you hours of confusion when building real-world applications.


What is multipart/form-data?

multipart/form-data is a content type used when your form needs to send a mix of data, such as text fields and files, in a single HTTP request.
Unlike JSON, which is designed for structured text data, multipart/form-data allows you to send both strings (like name, email, description) and binary data (like images, PDFs, etc.) together.


When Should You Use It?

The best use case for multipart/form-data is when your form includes file uploads.
For example:

Text fields → name, email, description
File fields → images, documents

This combination is not possible using standard JSON alone, which is why multipart/form-data becomes essential.


How It Works on the Frontend

On the frontend, we typically use the FormData API to construct the request:

const formData = new FormData();

formData.append("name", "John");
formData.append("email", "johndoe@gmail.com");
formData.append("description", "Some text");
formData.append("image", file);

Here, some values are plain strings, while others are actual file objects. This is the key distinction that makes multipart/form-data powerful.


What the Request Looks Like Internally

When the browser sends a multipart/form-data request, it doesn’t send it as a simple JSON object. Instead, it splits the request into multiple parts.

--boundary
Content-Disposition: form-data; name="name"

John

--boundary
Content-Disposition: form-data; name="email"

johndoe@gmail.com

--boundary
Content-Disposition: form-data; name="image"; filename="photo.jpg"
Content-Type: image/jpeg

(binary file data)

--boundary--

Each section is called a part, which is where the name multipart comes from.


How It Differs from JSON

JSON is clean and structured, but it only supports text-based data. A typical JSON request might look like:

{
  "name": "John",
  "email": "johndoe@gmail.com",
  "description": "Some text"
}

Notice that there is no way to directly include binary file data here.
That’s the limitation multipart/form-data solves.


Parsing multipart/form-data on the Backend

Since multipart/form-data is not as straightforward as JSON, it needs to be parsed before use.

{
  "name": "John",
  "email": "johndoe@gmail.com",
  "description": "Some text",
  "files": [
    {
      "filename": "photo.jpg",
      "contentType": "image/jpeg",
      "content": "<Buffer ff d8 ff e0 ...>"
    }
  ]
}

After parsing:
- Text fields remain strings
- Files become buffers with metadata (filename, type, etc.)


Important Caution: Never Set Content-Type Manually

One of the most common mistakes developers make is manually setting the Content-Type header like this:

Content-Type: multipart/form-data

This should not be done. The browser automatically sets the correct header:

Content-Type: multipart/form-data; boundary=----WebKitBoundaryXYZ

The boundary is critical. Without it, parsing may fail. That’s why it’s always advised not to set this header manually.


Why multipart/form-data Matters

multipart/form-data is fundamental for building modern applications that involve user uploads, forms, and media handling.

Whether you're building a profile upload feature, a blog CMS, or a file-sharing platform, understanding how this works gives you clarity on both frontend and backend communication.


In simple terms, whenever your data includes both text and files, multipart/form-data is the bridge that makes it possible to send everything together in one clean request.