Content-Disposition
response headercontent
Tells the browser to display a response inline or download it as a file, and with what file name.
Content-Disposition: attachment makes the browser download the response instead of displaying it, and filename suggests the name to save it under. inline (the default) displays it if the browser can, which is how PDFs open in a tab.
Syntax
Content-Disposition: inline | attachment[; filename="<name>"][; filename*=UTF-8''<encoded-name>]
Defined in RFC 6266 — Content-Disposition in HTTP.
Values
| inline | display in the browser if possible (default) |
|---|---|
| attachment | download instead of displaying |
| filename="…" | suggested file name (ASCII) |
| filename*=UTF-8''… | percent-encoded file name for non-ASCII characters |
Examples
Content-Disposition: attachment; filename="report.csv"
force a download
Content-Disposition: attachment; filename="resume.pdf"; filename*=UTF-8''r%C3%A9sum%C3%A9.pdf
non-ASCII name with an ASCII fallback
Content-Disposition: inline; filename="invoice.pdf"
open in the browser, but name it if saved
Good to know
- Strip quotes, slashes and line breaks from user-supplied file names before putting them in this header.
- The HTML
downloadattribute does the same for same-origin links:<a href="/report.csv" download>. - Serving user uploads as
attachmentalso stops them running as HTML on your origin.
Further reading: MIME types by file extension
How to set Content-Disposition
res.attachment("report.csv"); // sets Content-Disposition and Content-Type
res.send(csv);
// or stream a file from disk:
res.download("/data/report.csv", "report.csv");return new Response(csv, {
headers: {
"Content-Type": "text/csv; charset=utf-8",
"Content-Disposition": 'attachment; filename="report.csv"',
},
});from flask import send_file
return send_file("report.csv", as_attachment=True, download_name="report.csv")location /downloads/ {
add_header Content-Disposition "attachment" always;
}Check it
Fetch only the response headers and filter for Content-Disposition. In the browser, it's under Response Headers in DevTools → Network.
curl -sI https://example.com/ | grep -i '^content-disposition:'
To compare response headers across many URLs at once, use the HTTP Status Checker.
Frequently asked questions
How do I force a PDF to download instead of opening?
Serve it with Content-Disposition: attachment; filename="file.pdf". Users can still choose to open it afterwards.