Content-Disposition Header — How to Force Downloads and Control Filenames
The Content-Disposition HTTP header controls whether a file downloads or opens inline, and specifies the filename to save. Learn how attachment, inline, and filename* (RFC 5987) work, and why non-ASCII filenames break in older browsers.
Last updated:
Core Concepts
- attachment vs inline — the two modes
- Content-Disposition: inline means 'the browser should render this in-page if it can' (default for images, HTML, PDFs in modern browsers). Content-Disposition: attachment means 'always download this as a file.' The filename parameter specifies the suggested download name.
- The filename vs filename* distinction (RFC 5987)
- filename='report.pdf' uses ASCII only — non-ASCII characters in the filename will be mojibake (garbled) in older browsers. filename*=UTF-8''%E6%8A%A5%E5%91%8A.pdf encodes the filename in percent-encoded UTF-8, which handles any Unicode name (Japanese, Chinese, emoji). Modern browsers support both; always include filename* for non-ASCII filenames and filename as a fallback.
- Security: never trust user-supplied filenames
- A user-uploaded filename like '../../etc/passwd' or '..\..\windows\system32\config\sam' can cause path traversal if the server blindly uses it. Always sanitize: strip directory separators, prefix with a safe path, and optionally force a safe extension. Also, filenames with embedded ';' or '%00' (null byte) can truncate filenames in vulnerable implementations.
Frequently Asked Questions
How do I force a PDF to download instead of open in the browser?
Set Content-Disposition: attachment; filename='document.pdf' on the HTTP response. Without this header, modern browsers preview PDFs inline. With attachment, the browser shows a 'Save As' dialog.
Why is my Japanese filename showing as ??? in the download dialog?
The server is using filename='...' with unescaped non-ASCII characters. Switch to filename*=UTF-8'' plus a percent-encoded UTF-8 name. Also verify the charset of the HTTP response itself — it should declare UTF-8.
Try these related tools
URL Encode/Decode →
Percent-encode and decode URLs online. Handles query strings, path segments, and special characters correctly.
Punycode →
Convert internationalized (IDN) domain names to and from their ASCII xn-- form. Follows RFC 3492 exactly — the same encoding your browser and DNS resolver use. 100% local.