DevToys Web Pro iconDevToys Web ProБлог
Переведено с помощью LocalePack logoLocalePack
Оцените нас:
Попробуйте расширение для браузера:
← Back to Blog

MIME Types Guide: Content-Type Header, Sniffing, and Vendor Types

10 min read

Every HTTP response that carries a body includes a Content-Type header. That single header tells the browser, the CDN, and your API client what the bytes actually are — whether to render them as a web page, parse them as JSON, play them as video, or prompt the user to save a file. Getting it wrong breaks rendering, triggers security warnings, and can cause CORS preflight failures. Use the MIME Types Reference to look up any type as you read.

MIME Anatomy: type/subtype[; parameter]

A MIME type (Multipurpose Internet Mail Extensions type) has two required parts and one optional part:

type/subtype[; parameter=value]

# Examples
text/html; charset=utf-8
application/json
image/png
application/vnd.api+json; charset=utf-8

The type is a broad category. The subtype is the specific format within that category. The optional parameter adds extra metadata — most commonly a charset declaration. The IANA (Internet Assigned Numbers Authority) maintains the official registry of registered MIME types at https://www.iana.org/assignments/media-types/. Any type not in that registry is unofficial, though vendors routinely use unregistered types in practice.

Top-Level Types

There are nine standardized top-level types. Understanding them immediately narrows down what a type means before you even read the subtype:

TypeMeaningExamples
textHuman-readable texttext/html, text/plain, text/css
imageStill imagesimage/png, image/jpeg, image/webp
videoVideo mediavideo/mp4, video/webm
audioAudio mediaaudio/mpeg, audio/ogg
applicationBinary or application-specific dataapplication/json, application/pdf
multipartMultiple parts with different typesmultipart/form-data, multipart/mixed
messageEmail message encapsulationmessage/rfc822
fontFont filesfont/woff2, font/ttf
model3D model datamodel/gltf+json, model/obj

Common MIME Types

These are the types you encounter on almost every web project. Knowing them by heart prevents misconfiguration in nginx, Apache, Express, and CDN cache rules.

FormatMIME TypeNotes
HTMLtext/html; charset=utf-8Always include charset for HTML
JSONapplication/jsonUTF-8 is the default per RFC 8259
XMLapplication/xmltext/xml also valid but legacy
PDFapplication/pdfBrowser may render inline or download
JPEGimage/jpegimage/jpg is not an IANA type
PNGimage/png
WebPimage/webp
SVGimage/svg+xmlStructured suffix +xml
MP4video/mp4
CSVtext/csvExcel ignores this — see pitfalls
JavaScripttext/javascriptapplication/javascript is obsolete per RFC 9239
CSStext/css
WebAssemblyapplication/wasmRequired for streaming compilation
WOFF2font/woff2

Charset Parameter

The charset parameter declares the character encoding of text content:

Content-Type: text/html; charset=utf-8
Content-Type: text/plain; charset=iso-8859-1
Content-Type: text/csv; charset=utf-8

For text/* types, always declare charset=utf-8 explicitly. Without it, some older parsers default to ISO-8859-1, which breaks any non-ASCII content including curly quotes, em dashes, and accented characters.

JSON is a notable exception. RFC 8259 mandates UTF-8 as the only permitted encoding for JSON exchanged between systems that are not part of a closed ecosystem. Sending charset=utf-8 alongside application/json is harmless but redundant — the charset is already implicit. You will still see it in the wild:

# Both are acceptable for JSON responses
Content-Type: application/json
Content-Type: application/json; charset=utf-8

Vendor-Specific Types

The vnd. prefix (vendor) indicates a format specific to a company or product. These are registered with IANA but defined by the vendor, not a standards body. You encounter them constantly in enterprise APIs and Microsoft Office files:

MIME TypeFormat
application/vnd.api+jsonJSON:API specification responses
application/vnd.ms-excelLegacy Excel (.xls)
application/vnd.openxmlformats-officedocument.spreadsheetml.sheetModern Excel (.xlsx)
application/vnd.openxmlformats-officedocument.wordprocessingml.documentWord document (.docx)
application/vnd.openxmlformats-officedocument.presentationml.presentationPowerPoint (.pptx)
application/vnd.google-apps.documentGoogle Docs internal format
application/vnd.docusign+jsonDocuSign envelope JSON

The application/vnd.api+json type is worth calling out specifically. JSON:API is a specification for structuring API request and response payloads. When a server returns this type, the client knows the body follows JSON:API conventions — top-level data, errors, and meta keys, relationship links, and so on. Setting the wrong type here (application/json instead of application/vnd.api+json) breaks content negotiation for strict JSON:API clients.

Structured Suffixes

Structured suffixes communicate the underlying serialization format independently of the specific type. The suffix comes after a + in the subtype:

image/svg+xml          # SVG is XML
application/vnd.api+json   # JSON:API is JSON
model/gltf+json        # glTF 3D model serialized as JSON
application/atom+xml   # Atom feed is XML

The +json suffix tells parsers they can apply a JSON parser to the body even if they do not specifically understand the full type. Similarly, +xml means a generic XML parser will work. The +zip suffix (used by the Office Open XML formats) signals that the file is a ZIP archive — a .docx is literally a ZIP containing XML files, which is why its MIME type is application/vnd.openxmlformats-officedocument.wordprocessingml.document with the underlying container being a ZIP.

How Browsers Use MIME Types

The Content-Type header is the primary signal browsers use to decide what to do with a response body. The decision tree is roughly:

  • text/html — parse as HTML and render the page
  • text/css — apply as a stylesheet (only if fetched as a CSS resource)
  • text/javascript — execute as JavaScript (only if fetched as a script)
  • image/* — decode and display the image
  • video/*, audio/* — play in the media player
  • application/pdf — render in the built-in PDF viewer (Chrome, Firefox)
  • application/octet-stream — generic binary data; always triggers a download
  • application/json — display as raw text in the browser, not rendered as HTML

The application/octet-stream type is the safe default for file downloads. If you serve a file with this type, the browser will always prompt to save it regardless of the actual content. Use it when you want a download behavior even for types the browser could otherwise render, such as PDF or SVG.

# Forces download even for HTML content
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="export.html"

MIME Sniffing and X-Content-Type-Options: nosniff

Browsers do not always trust the Content-Type header blindly. When the declared type seems wrong or is missing, browsers perform MIME sniffing — they inspect the first bytes of the response body and guess the actual type. This behavior exists for historical compatibility with misconfigured servers.

MIME sniffing creates a security vulnerability. If an attacker uploads a file that begins with HTML but is served with Content-Type: image/png, a sniffing browser may execute it as HTML and run any embedded scripts. This is a variant of cross-site scripting.

The defense is the X-Content-Type-Options: nosniff response header:

X-Content-Type-Options: nosniff

When nosniff is set, the browser honors the declared Content-Type exactly and refuses to override it. If the type says image/png, the browser treats it as an image — it will not sniff the body and re-classify it as HTML. The consequence is that a wrong Content-Type will cause the resource to fail to load rather than silently work due to sniffing.

Beyond script injection, nosniff also prevents browsers from loading cross-origin responses as a different resource type than declared, which closes off certain side-channel information leaks. Every application should set this header on all responses.

# Correct combination for a JSON API
Content-Type: application/json
X-Content-Type-Options: nosniff

# Correct combination for an HTML page
Content-Type: text/html; charset=utf-8
X-Content-Type-Options: nosniff

Content-Disposition

While Content-Type says what the data is, Content-Disposition says how it should be presented. The two values are inline (default, display in browser) and attachment (download):

# Display in browser if possible
Content-Disposition: inline

# Trigger download with suggested filename
Content-Disposition: attachment; filename="report-2026-04.csv"

# UTF-8 encoded filename (RFC 5987)
Content-Disposition: attachment; filename*=UTF-8''rapport-%C3%A0-t%C3%A9l%C3%A9charger.csv

Filenames with non-ASCII characters require RFC 5987 encoding using the filename* parameter (note the asterisk). The format is charset'language'percent-encoded-value. For broad compatibility, include both filename (ASCII fallback) and filename* (UTF-8):

Content-Disposition: attachment; filename="download.pdf"; filename*=UTF-8''t%C3%A9l%C3%A9chargement.pdf

Common Pitfalls

Several real-world problems stem directly from incorrect MIME handling:

  • Wrong Content-Type breaks CORS preflight. When a browser sends a cross-origin POST with Content-Type: application/json, it triggers a preflight OPTIONS request. If the server is not configured to handle OPTIONS or the declared type does not match what the server expects, the preflight fails and the actual request is never sent. The fix is ensuring the server explicitly allows the content type in its Access-Control-Allow-Headers response.
  • Excel ignores MIME types. Serving a CSV file with Content-Type: text/csv does not make Excel open it correctly — Excel uses file extension, not MIME type, for format detection. When generating Excel-targeted downloads, use application/vnd.openxmlformats-officedocument.spreadsheetml.sheet and produce a real .xlsx file, not a renamed CSV.
  • Email attachments use different rules. Email clients (Outlook, Gmail) rely on MIME types in multipart/mixed messages to determine how to render attachments. An attachment served as application/octet-stream may be blocked by mail security filters. Use specific types like application/pdf when possible.
  • Server default MIME maps are incomplete. Web servers like nginx and Apache ship with a mime.types file that maps file extensions to MIME types. This file often omits newer formats: .webp, .wasm, .woff2, and .avif may need to be added explicitly. Missing entries cause the server to fall back to application/octet-stream, which prevents browsers from rendering the resource correctly.
  • image/jpg is not a valid MIME type. The correct type is image/jpeg. Hardcoding image/jpg in server config or application code causes type mismatches that surface as broken images in strict clients.
  • WebAssembly requires the exact type. Browsers only enable streaming compilation (WebAssembly.instantiateStreaming) when the response carries application/wasm exactly. Any other type — including application/octet-stream — forces the slower non-streaming path and may trigger a console warning.

Look up the correct MIME type for any file format in the MIME Types Reference. Related reading: HTTP Status Codes Guide and Web Payload Workflow.