다운로드한 파일의 한글 이름이 깨질 때: Content-Disposition 헤더 확인법

웹 브라우저에서 첨부파일을 다운로드할 때 저장 대화상자에 나타나는 파일명이 깨지거나, 밑줄이나 퍼센트 기호로 뒤덮인 영문자로 저장되는 경우가 있습니다. 이 문제는 파일 본문의 인코딩 문제와는 별개로, 웹 서버가 내려주는 HTTP 응답 헤더 중 Content-Disposition의 설정 방식 때문에 발생합니다.

MDN의 Content-Disposition 문서에 명시된 규칙을 바탕으로 한글 파일명을 안전하게 전달하는 헤더 작성법과 브라우저 호환성을 위한 점검 순서를 살펴봅니다.

파일명 표기와 본문 인코딩의 차이

웹 다운로드에서 흔히 혼동하는 두 가지 영역이 있습니다. 하나는 운영체제 탐색기에 표시되는 ‘파일 자체의 이름’이고, 다른 하나는 다운로드 완료 후 파일을 열었을 때 보이는 ‘파일 본문 내용’입니다.

파일 내부의 텍스트가 깨진다면 한글 파일 깨짐: UTF-8 인코딩 확인하는 순서에서 다룬 것처럼 문서 자체의 문자 집합(UTF-8, EUC-KR 등)이나 Content-Type의 charset 설정을 확인해야 합니다. 반면, 파일 내부 내용은 멀쩡한데 오직 내려받을 때 정해지는 파일 이름만 깨진다면 이는 HTTP 응답 헤더인 Content-Disposition의 파라미터 규격을 점검해야 합니다.

filename과 filename* 파라미터의 역할

HTTP 응답 헤더에서 브라우저에게 파일 다운로드를 지시할 때는 attachment 지시자를 사용하며, 기본 저장 파일명을 제안할 때 filename과 filename* 매개변수를 덧붙입니다.

파라미터표준 인코딩 규격브라우저 처리 우선순위권장 용도
filenameUS-ASCII하위 호환 대체값ASCII 영문/숫자 안전 파일명 제안
filename*RFC 5987 (UTF-8''퍼센트인코딩)filename보다 우선 적용한글, 다국어 파일명 온전한 전달

표준 규격에 따르면 filename은 원칙적으로 US-ASCII 문자를 전제로 설계되었습니다. 한글과 같은 비ASCII 문자를 filename="안내문.txt"처럼 직접 넣거나 임의로 퍼센트 인코딩(%EC%95%88...)을 넣으면 브라우저 구현에 따라 다르게 해석됩니다. 예를 들어 일부 브라우저는 퍼센트 인코딩을 디코딩하지만 사파리(Safari)와 같은 브라우저는 이를 디코딩하지 않아 파일명에 퍼센트 기호가 그대로 남는 문제가 생깁니다.

따라서 RFC 5987 규격을 따르는 filename* 지시자를 함께 선언해야 합니다. 두 파라미터가 모두 주어지면 규격을 지원하는 현대 브라우저는 filename*의 값을 우선적으로 해석합니다.

재현 입력과 안전한 헤더 작성

가상의 파일 안내문.txt를 내려받는 상황을 재현해 보겠습니다. 한글 '안내'와 '문'을 UTF-8 바이트로 변환한 뒤 퍼센트 인코딩하면 다음과 같습니다.

  • '안': %EC%95%88
  • '내': %EB%82%B4
  • '문': %EB%AC%B8

이를 RFC 5987 규칙(인코딩 선언 UTF-8'' 뒤에 인코딩된 문자열 연결)에 맞추고, 비ASCII를 이해하지 못하는 구형 환경을 위해 안전한 영문 대체 파일명 note.txt를 filename에 지정한 표준 응답 헤더는 아래와 같습니다.

Content-Disposition: attachment; filename="note.txt"; filename*=UTF-8''%EC%95%88%EB%82%B4%EB%AC%B8.txt

이 헤더가 전달되었을 때의 처리 방식과 본문 인코딩과의 차이를 정리한 검증 기준은 다음과 같습니다.

가상 파일 안내문.txt에 대한 filename*=UTF-8''... 예제와 ASCII 대체 파일명 note.txt를 비교한다. 실제 파일 내용이 깨지는 문제는 이 헤더만으로 해결되지 않는다.

안전한 점검 및 적용 순서

서버 응답에서 한글 파일명이 올바르게 동작하도록 수정하는 안전한 절차는 다음과 같습니다.

  1. 네트워크 탭에서 원본 헤더 확인: 개발자 도구의 네트워크(Network) 패널에서 파일 다운로드 요청을 선택하고, 응답 헤더(Response Headers)의 Content-Disposition 값을 직접 확인합니다.
  2. 인코딩 형식 분리 점검: filename에 원시 한글 바이트가 그대로 들어가 있거나 임의의 퍼센트 인코딩이 들어있는지 확인합니다.
  3. 이중 파라미터 구성: 표준에 맞추어 영문 ASCII 대체 이름(filename="...")과 RFC 5987 규격의 한글 이름(filename*=UTF-8''...)을 함께 응답에 포함하도록 서버 로직을 구성합니다.
  4. 저장 시 특수문자 변환 검토: 파일명에 /나 \ 같은 경로 구분자가 들어있으면 브라우저가 파일 시스템 보호를 위해 이를 밑줄(_) 등으로 치환하므로 경로 기호가 섞이지 않도록 사전에 정리합니다.

실패 사례와 한계

이 헤더 구성을 적용해도 해결되지 않거나 주의해야 할 한계 상황이 존재합니다.

  • 파일 내부 텍스트 깨짐 미해결: 서두에서 언급했듯, 이 헤더는 운영체제에 전달되는 파일 명칭만 결정합니다. 메모장으로 열었을 때 글자가 깨지는 현상은 파일 본문의 인코딩 문제이므로 파일 자체의 저장을 UTF-8 등으로 다시 변환해야 합니다.
  • HTML a 태그의 download 속성 우선순위: HTML 문서 내부의 <a download="..."> 속성과 Content-Disposition: inline이 만났을 때는 태그의 download 속성이 다운로드를 유발하지만, 응답 헤더에 명시적인 filename 파라미터가 있다면 헤더의 파일명이 다운로드 속성의 이름을 덮어씁니다.
  • 브라우저와 파일 시스템 제약: 파일명 길이가 지나치게 길거나 운영체제가 금지하는 특수문자(Windows 금지 문자와 예약 이름 참조)가 포함된 경우 브라우저나 OS가 강제로 이름을 변경하거나 저장을 거부할 수 있습니다.

참고 자료와 확인 범위

아래 자료는 형식·기능의 정의를 확인하는 데 사용했습니다. 본문의 예제와 설명은 이 사이트의 작업 상황에 맞춰 구성했습니다. 제품 메뉴는 버전과 언어에 따라 다를 수 있습니다.

확인일: 2026-10-23 · 오류를 발견하면 이 글의 오류 신고로 알려주세요.