HTTP Content Types: MIME Types in Web Requests

HTTP Content-Type is a header that specifies the format of data in a request or response, such as text/html or application/json.

HTTP Content-Type

The HTTP Content-Type header tells the sender and receiver what kind of data is being transferred. Without it, browsers and servers would have to guess the format of incoming data, leading to parsing errors, broken layouts, and security vulnerabilities that are straightforward to prevent.

What Is a Content-Type

Content-Type is an HTTP header that identifies the media type, also called the MIME type, of the data being sent in an HTTP message body. It appears in both requests, when a client sends form data or a JSON payload to a server, and in responses, when a server returns HTML, an image, API data, or any other resource.

The value of a Content-Type header consists of a primary type and a subtype separated by a forward slash, such as text/html or application/json. It can also include optional parameters after a semicolon, most commonly the character encoding such as charset=UTF-8 for text-based content.

In a request (client sending JSON to the server):
POST /api/users HTTP/1.1
Content-Type: application/json

{"name": "Alice", "email": "alice@example.com"}
In a response (server returning an HTML page):
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html>
<html>...</html>

Common MIME Types

MIME types are organised into categories. The part before the slash indicates the general category such as text, image, audio, video, or application. The part after the slash specifies the exact format. Here are the most commonly encountered MIME types in web development.

MIME TypeUsed For
text/htmlHTML web pages returned by web servers and rendered by browsers
text/cssCSS stylesheets. If served with the wrong type, browsers will refuse to apply the styles.
text/javascriptJavaScript files. The formerly used application/javascript is now deprecated in favour of this type.
text/plainPlain unformatted text with no special rendering instructions
application/jsonJSON data, the standard format for REST API request and response bodies
application/xmlXML data used in SOAP APIs, RSS feeds, and legacy enterprise integrations
application/x-www-form-urlencodedStandard HTML form submissions where field names and values are URL-encoded in the request body
multipart/form-dataForm submissions that include file uploads, where each field is sent as a separate part
image/jpegJPEG compressed images, commonly used for photographs
image/pngPNG images with lossless compression, commonly used for graphics and screenshots
image/webpWebP images offering superior compression compared to JPEG and PNG for most use cases
image/svg+xmlSVG vector images that scale without quality loss, commonly used for icons and illustrations
image/gifGIF images supporting animation, though largely replaced by video formats for animated content
application/octet-streamGeneric binary data with an unknown or unspecified format. Browsers typically trigger a file download for this type.
application/pdfPDF documents, which browsers can render inline or prompt to download depending on settings
audio/mpegMP3 audio files used for music and podcasts
video/mp4MP4 video files, the most widely supported video format for web delivery
font/woff2Web Open Font Format 2, the preferred format for web fonts due to its small file size

Content-Type vs the Accept Header

Content-Type and Accept are companion headers that together enable content negotiation, a process where the client and server agree on the format of the data being exchanged. They travel in opposite directions and serve opposite purposes.

HeaderDirectionMeaningExample
Content-TypeSent by whoever is sending a body, whether client or serverDeclares the format of the data included in the current message bodyContent-Type: application/json
AcceptSent by the client in requestsDeclares the formats the client is able to process in the responseAccept: application/json, text/html

When a client sends a request with Accept: application/json, it is telling the server it prefers a JSON response. The server reads this header and, if it supports JSON, responds with Content-Type: application/json in the response. If the server cannot produce the requested format, it returns a 406 Not Acceptable status code. This negotiation allows a single API endpoint to serve different formats to different clients without requiring separate URLs.

The charset Parameter

For text-based content types, the Content-Type header should include a charset parameter specifying the character encoding. Without it, browsers may use a default encoding that produces garbled text for non-ASCII characters.

Content-Type: text/html; charset=UTF-8
Content-Type: text/plain; charset=UTF-8
Content-Type: application/json; charset=UTF-8

UTF-8 is the correct and universally recommended character encoding for all text-based web content. It supports every character in the Unicode standard and is the default encoding assumed by the JSON specification, so including charset=UTF-8 on application/json responses is technically redundant but harmless and occasionally helpful for compatibility with older parsers.

Why Content-Type Matters for Security

When a Content-Type header is missing or incorrect, browsers may attempt to determine the format by examining the content itself, a behaviour called MIME sniffing. This can create a serious security vulnerability. If an attacker uploads a file containing HTML or JavaScript but with a harmless-looking filename, and the server serves it without a Content-Type header, some browsers may sniff the content, determine it looks like HTML, and execute it as a web page in the context of your domain. This can lead to cross-site scripting attacks.

The X-Content-Type-Options: nosniff response header instructs browsers to strictly follow the declared Content-Type and never attempt to sniff the format. It should be included on all responses, particularly those serving user-uploaded content.

Recommended security headers alongside Content-Type:
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff

Content-Type in Form Submissions

HTML forms can submit data using two different encoding formats, and the Content-Type header determines which one is used. The default is application/x-www-form-urlencoded, which encodes field names and values as URL-encoded key-value pairs in the request body. This works well for simple text fields but cannot handle binary data or file uploads.

When a form includes a file input, the encoding must be changed to multipart/form-data by setting the enctype attribute on the form element. This format splits the request body into multiple parts, each with its own headers, allowing binary file data to be transmitted alongside text fields without encoding issues.

HTML form with file upload (uses multipart/form-data automatically):
<form method="POST" action="/upload" enctype="multipart/form-data">
  <input type="text" name="username">
  <input type="file" name="avatar">
  <button type="submit">Upload</button>
</form>

Frequently Asked Questions

  1. What happens if the Content-Type header is wrong or missing?
    The consequences depend on the mismatch. A CSS file served as text/plain will not be applied by the browser because browsers refuse to use stylesheets served with the wrong MIME type. A JSON response declared as text/html may cause client parsers to fail or produce unexpected results. A JavaScript file served with an incorrect type may be blocked by the browser's strict MIME type checking. Always set Content-Type accurately to match the actual format of the data being sent.
  2. What is the difference between application/json and text/json?
    application/json is the correct and officially registered MIME type for JSON data, defined in RFC 8259. text/json is non-standard and not recognised by most parsers and frameworks. Always use application/json for REST API responses and request bodies. Using a non-standard type can cause parsing failures in HTTP clients, CDNs, and API gateways that validate content types.
  3. Do GET requests need a Content-Type header?
    No. Content-Type is only relevant when a message includes a body. GET and HEAD requests typically have no body, so there is nothing to declare a type for and the header should be omitted. Content-Type is required on requests that include a body such as POST, PUT, and PATCH, and on all responses that return data in the body.
  4. Why does my browser download a file instead of displaying it?
    When a server responds with Content-Type: application/octet-stream or includes a Content-Disposition: attachment header, the browser treats the response as a file to be saved rather than content to be rendered. If you want the browser to display a file inline, ensure the response uses the correct MIME type for the content, such as application/pdf for PDFs or image/jpeg for images, and omit the Content-Disposition header or set it to inline.
  5. Can a single endpoint return different Content-Types?
    Yes, through content negotiation. The client includes an Accept header in the request specifying which formats it can process. The server inspects this header and responds with the most appropriate format it supports, declaring the chosen type in the Content-Type response header. For example, a browser requesting a page might send Accept: text/html while an API client sends Accept: application/json. The server can detect this and return the same data in the appropriate format for each client from the same URL.

Conclusion

Content-Type is a small but critical header that prevents parsing errors, broken layouts, and security vulnerabilities across every HTTP interaction. Setting it accurately on all API responses, form submissions, and static file deliveries is a fundamental web development practice that costs nothing and prevents a wide range of problems. Always pair it with X-Content-Type-Options: nosniff to prevent MIME sniffing attacks, use charset=UTF-8 for all text-based responses, and use the Accept header to enable content negotiation where multiple formats are needed. See also HTTP headers and REST APIs for related guidance on building well-configured web services.