
Content-Disposition 헤더 사용 기준 정리
Content-Disposition은 브라우저가 응답 본문을 화면에 그대로 표시할지, 다운로드 대상으로 다룰지를 정하는 HTTP 헤더다. 2026년 6월 23일 확인 기준 MDN, RFC 6266, RFC 7578을 보면 이 헤더는 inline, attachment, filename, filename* 같은 지시어로 동작이 갈린다.
실무에서 자주 헷갈리는 지점은 세 가지다. 파일 다운로드를 강제하려면 어떤 값을 써야 하는지, 한글이나 공백이 있는 파일명은 어떻게 보내야 하는지, 그리고 업로드용 multipart/form-data 파트에서도 같은 규칙이 그대로 적용되는지다. 이 글은 공식 문서 기준으로 그 차이를 짧게 정리한다.
Content-Disposition은 무엇을 제어할까?
MDN은 Content-Disposition을 응답 콘텐츠를 웹페이지로 표시할지, 로컬에 저장할 첨부 파일로 다룰지 나타내는 헤더로 설명한다. 가장 흔한 값은 inline과 attachment다.
inline: 브라우저가 가능한 경우 화면 안에서 바로 표시한다.attachment: 브라우저가 보통 다운로드 동작으로 처리하고, 저장 대화상자에 파일명을 제안할 수 있다.
다만 실제 표시 가능 여부는 Content-Type과 브라우저 지원에도 영향을 받는다. 예를 들어 브라우저가 렌더링 가능한 PDF나 이미지라면 inline일 때 화면에서 열릴 수 있고, 그렇지 않으면 다운로드될 수 있다.
다운로드 강제에는 무엇을 쓰면 될까?
브라우저에 저장 동작을 유도하려면 일반적으로 Content-Disposition: attachment를 사용한다. MDN과 RFC 6266 예시는 이 값이 "Save As" 동작을 유도하는 대표 형태라고 설명한다.
반대로 헤더를 아예 보내지 않거나 inline을 쓰면 브라우저는 해당 콘텐츠를 가능한 범위에서 직접 표시하려고 시도한다. 따라서 문서 보기와 다운로드를 확실히 구분하고 싶다면 응답마다 의도를 명시하는 편이 안전하다.
filename과 filename*은 어떻게 다른가?
filename은 저장 제안 파일명을 전달하는 오래된 형태이고, filename*은 RFC 5987 인코딩을 이용해 비ASCII 문자를 표현할 수 있는 확장 형태다. MDN은 두 값이 함께 있으면 이를 이해하는 브라우저에서는 filename*이 우선된다고 설명한다.
RFC 6266도 같은 방향의 예시를 제공한다. 즉 한글, 일본어, 유로 기호처럼 ASCII 밖의 문자가 들어갈 수 있다면 filename*을 포함하고, 호환성을 위해 ASCII 대체 문자열을 filename에 함께 두는 구성이 가장 무난하다.
Content-Disposition: attachment;
filename="report-q2.pdf";
filename*=UTF-8''report-%ED%95%9C%EA%B8%80.pdf
MDN은 filename 쪽의 퍼센트 인코딩은 브라우저별 처리 차이가 있을 수 있다고 설명한다. 따라서 비ASCII 파일명을 안정적으로 다루려면 filename*을 기준으로 보고, filename은 ASCII fallback으로 두는 편이 낫다.
공백, 경로 구분자, 특수문자는 어떻게 봐야 할까?
MDN은 공백처럼 특수 문자가 들어가면 filename 값을 따옴표로 감싸는 편이 안전하다고 설명한다. 또한 브라우저는 파일 시스템 제약에 맞추기 위해 /나 \ 같은 경로 구분자를 밑줄 등으로 바꿀 수 있다.
RFC 6266과 RFC 7578은 수신 측이 서버가 보낸 파일명을 그대로 신뢰하면 안 된다고 본다. 경로 정보 제거, 기존 파일 덮어쓰기 방지, 운영체제에서 위험한 특수 파일명 회피 같은 방어가 필요하다는 뜻이다.
multipart/form-data에서도 filename*을 쓰면 될까?
여기서 규칙이 갈린다. 일반 HTTP 응답 헤더에서는 filename*을 사용할 수 있지만, 업로드용 multipart/form-data 각 파트의 Content-Disposition에서는 RFC 7578이 filename*을 쓰지 말아야 한다고 명시한다.
RFC 7578 4.2절은 파일 파트에서 filename 사용을 설명하고, 이어서 RFC 5987 방식의 filename* 파라미터는 multipart/form-data 안에서는 사용하면 안 된다고 적고 있다. 즉 다운로드 응답과 업로드 폼 파트는 같은 헤더 이름을 쓰더라도 세부 규칙이 완전히 같지 않다.
download 속성과 헤더가 충돌하면 무엇이 우선일까?
MDN은 same-origin URL에 대해서는 Chrome과 Firefox 82 이상에서 <a download> 속성이 Content-Disposition: inline보다 우선할 수 있다고 설명한다. 따라서 브라우저 내 링크 클릭 동작과 직접 응답 열기 동작이 항상 같다고 보면 안 된다.
운영 기준으로는 서버 헤더만 보고 판단하지 말고, 실제 다운로드 링크를 <a download>로 제공하는지까지 함께 확인하는 편이 정확하다.
어떤 기준으로 선택하면 될까?
- 브라우저에서 바로 보여도 되는 문서나 미디어라면
inline또는 헤더 생략을 검토할 수 있다. - 저장 동작을 명확히 유도해야 하면
attachment를 우선 검토한다. - 비ASCII 파일명이 필요하면
filename*을 포함하고, 호환용 ASCIIfilename을 함께 둔다. - 업로드 폼 파트에서는 응답 헤더 규칙을 그대로 복사하지 말고 RFC 7578 제약을 따로 확인한다.
마지막 항목은 문서 차이에서 직접 나오는 운영 기준이다. 특히 다운로드 응답과 업로드 파서 구현을 같은 코드 경로에서 처리할 때 혼동이 많이 생긴다.
FAQ
Q. attachment를 쓰면 모든 브라우저에서 반드시 다운로드만 될까?
공식 문서는 일반적으로 다운로드 동작을 유도한다고 설명하지만, 실제 사용자 경험은 브라우저 UI와 플랫폼 정책의 영향을 받을 수 있다. 다만 서버 의도를 가장 분명하게 표현하는 값이 attachment라는 점은 문서상 일관된다.
Q. filename만 보내도 한글 파일명이 항상 안전할까?
아니다. MDN은 filename과 filename*의 처리 차이를 설명하고, 최대 호환성을 위해 둘을 함께 두는 방식을 권장한다. 비ASCII 문자를 안정적으로 표현하려면 filename*이 핵심이다.
Q. multipart/form-data 업로드에서도 filename*을 받도록 구현해도 될까?
현실 구현체는 다양한 입력을 보낼 수 있지만, 표준 문서 기준으로는 multipart/form-data 안의 filename*은 사용하지 않아야 한다. 범용 파서를 만든다면 허용 여부와 별개로 비표준 입력 처리 정책을 분리해서 두는 편이 안전하다.
정리
Content-Disposition은 단순히 다운로드 여부만 정하는 헤더가 아니라, 파일명 인코딩과 브라우저 동작 차이까지 함께 다뤄야 하는 헤더다. 2026년 6월 23일 확인 기준으로 일반 응답에서는 attachment와 filename* 조합이 자주 기준점이 되고, multipart/form-data에서는 RFC 7578 제약을 별도로 봐야 한다.
실무에서는 다운로드 응답, HTML 링크, 업로드 파트 파싱을 한 번에 묶어 생각하지 않는 것이 중요하다. 같은 이름의 헤더라도 맥락에 따라 허용 파라미터와 호환성 포인트가 다르기 때문이다.
참고 자료
'프로그래밍 > HTML, Javascript, CSS' 카테고리의 다른 글
| Permissions-Policy 헤더 기준 정리 (0) | 2026.07.04 |
|---|---|
| Clear-Site-Data 헤더 기준 정리 (1) | 2026.06.28 |
| Fetch Metadata 헤더 기준 정리 (0) | 2026.06.21 |
| Trusted Types 적용 기준 정리 (0) | 2026.06.17 |
| Strict-Transport-Security 설정 기준 정리 (0) | 2026.06.12 |





