HTML 폼에서 첨부 파일 내용이 전송되지 않을 때: enctype 속성 확인법

웹 페이지에서 파일 첨부 창(<input type="file">)을 두고 문서를 전송했는데, 서버에 파일 내용(바이너리)은 전혀 들어오지 않고 파일 이름 문자열만 전달되는 현상을 겪을 수 있습니다. 화면에서는 정상적으로 파일이 선택되었고 양식 제출 버튼도 동작하지만, 서버 측 파서에서는 빈 파일이거나 단순 텍스트로 인식됩니다.

이 문제의 가장 흔한 원인은 양식을 감싸는 <form> 태그에 enctype 속성을 지정하지 않아 브라우저 기본 전송 방식이 적용되었기 때문입니다. 브라우저가 파일 데이터를 전송하는 규격과 필수 속성 점검 순서를 정리합니다.

파일 본문 대신 파일 이름만 전송되는 증상과 재현

다음은 문제가 발생하는 전형적인 양식 구조와 이를 해결하는 기준 검증 예제입니다.

<form action="/upload" method="post"><input type="file" name="uploadFile"><button type="submit">전송</button></form> 코드는 기본 인코딩(application/x-www-form-urlencoded)을 사용하여 실제 파일 내용이 전송되지 않습니다. form 태그에 enctype="multipart/form-data" 속성을 추가하면 HTTP 요청 헤더에 multipart 경계값이 포함되며 선택한 파일 바이너리가 서버로 온전히 전달됩니다.

별도의 인코딩 속성을 지정하지 않은 양식에서 파일을 선택하고 전송하면 브라우저는 HTTP 요청 본문에 파일의 실제 바이너리 데이터를 싣지 않습니다. 개발자 도구의 네트워크 탭에서 확인해 보면 전송 페이로드에 uploadFile=sample.pdf처럼 선택한 파일의 이름만 일반 문자열 형태로 포함된 것을 볼 수 있습니다.

결과적으로 서버는 들어온 데이터를 일반 텍스트 매개변수로만 처리할 수 있으며, 디스크에 저장하거나 처리할 파일 스트림 자체가 존재하지 않아 업로드 실패나 빈 파일 오류를 발생시킵니다.

기본 인코딩과 multipart/form-data의 구조적 차이

MDN form 요소 명세에 따르면, <form>의 method 속성이 post일 때 양식 데이터를 직렬화하는 방식을 결정하는 속성이 바로 enctype(Encoding Type)입니다.

enctype 값기본 여부데이터 처리 방식파일 첨부 시 동작
application/x-www-form-urlencoded기본값 (생략 시)모든 문자를 URL 인코딩 형식(키=값&키=값)으로 변환파일의 이름(텍스트)만 전송되고 본문 누락
multipart/form-data명시적 지정 필요각 입력값을 독립된 경계(boundary) 파트로 분리 전송파일 본문(바이너리)과 메타데이터가 온전히 전달됨
text/plain명시적 지정 필요인코딩 없이 공백만 +로 바꾸어 전송 (디버깅용)파일 내용 전송에 부적합

기본값인 application/x-www-form-urlencoded는 이름, 아이디, 비밀번호와 같은 짧은 텍스트 필드를 전송하기 위해 설계되었습니다. 이 방식은 대용량 바이너리 스트림을 다루지 못하므로 파일 필드에 대해서는 파일 이름 텍스트만 추출해 직렬화합니다.

반면 multipart/form-data를 선언하면 브라우저가 임의의 경계 문자열(boundary)을 생성하고, 텍스트 필드와 파일 필드를 각각 별도의 파트로 분할합니다. 각 파일 파트에는 파일 이름뿐만 아니라 원본 파일 내용 전체가 그대로 실리게 됩니다.

안전한 파일 전송을 위한 폼 점검 순서

양식에서 파일이 누락되지 않도록 태그를 구성할 때는 다음 순서로 코드를 점검해야 합니다.

  1. HTTP 메서드 확인: <form> 태그의 method 속성이 대소문자 무관하게 post로 지정되어 있는지 확인합니다. 기본값인 get 상태에서는 주소 표시줄 뒤에 데이터가 붙는 쿼리스트링 구조이므로 파일 바이너리를 담을 수 없습니다.
  2. enctype 속성 명시: <form> 시작 태그 내부에 enctype="multipart/form-data"를 정확히 기재합니다. 오탈자가 나면 브라우저가 기본값으로 되돌릴 수 있습니다.
  3. 입력 필드의 name 속성 확인: <input type="file"> 태그에 고유한 name 속성이 부여되어 있는지 확인합니다. name이 없으면 브라우저 직렬화 대상에서 완전히 제외됩니다.
  4. 제출 버튼 확인: 양식을 전송하는 버튼이 정상적인 제출 동작을 수행하는지 확인합니다. 양식 내부 버튼의 기본 동작 방식은 버튼 클릭 시 페이지가 새로고침될 때: button type 속성 기본값 확인법에서 다룬 규칙을 따릅니다.
  5. 네트워크 페이로드 검증: 브라우저 개발자 도구의 네트워크(Network) 탭에서 제출 요청의 헤더를 확인합니다. Content-Type 헤더에 multipart/form-data; boundary=...가 나타나고 요청 크기가 파일 크기만큼 커졌는지 점검합니다.

formenctype 덮어쓰기와 흔한 설정 누락 사례

폼 태그에 올바르게 enctype="multipart/form-data"를 적었더라도 파일이 넘어가지 않는 특수한 경우가 있습니다. 바로 제출을 트리거하는 버튼에 formenctype 속성이 선언된 경우입니다.

HTML 표준에 따르면 <button>, <input type="submit">, <input type="image"> 요소에 부여된 formenctype 속성은 상위 <form> 태그의 enctype 설정을 덮어씁니다. 만약 제출 버튼에 과거 테스트 목적으로 formenctype="application/x-www-form-urlencoded"가 남아 있다면, 폼 태그의 multipart 설정이 무시되고 파일 본문이 전달되지 않습니다.

반대로 양식 전체가 기본 인코딩으로 동작해야 하지만 특정 제출 버튼에서만 파일 업로드를 수행해야 할 때는 해당 버튼에만 formenctype="multipart/form-data"를 명시적으로 부여해 전송 방식을 재정의할 수 있습니다.

enctype 설정만으로 검증할 수 없는 한계

HTML 폼에 enctype="multipart/form-data"를 지정하는 것은 브라우저가 HTTP 요청 본문에 파일 바이너리를 온전히 실어 보내도록 지시하는 규격 준수 과정일 뿐입니다. 클라이언트 양식 수정만으로는 다음과 같은 문제를 해결할 수 없습니다.

  • 서버 측 멀티파트 파서 부재: 서버 애플리케이션에 멀티파트 요청을 해석하는 미들웨어나 파서가 등록되어 있지 않으면 전송된 원시 바이너리를 읽어내지 못합니다.
  • 웹 서버 크기 제한 초과: 파일 본문이 브라우저에서 전송되더라도 웹 서버의 본문 크기 제한을 초과하면 전송이 차단될 수 있습니다. 용량 단위 차이에 따른 업로드 한계 계산은 10MB 첨부 제한: MB와 MiB 차이부터 확인하기를 참고할 수 있습니다.
  • 스크립트 기반 비동기 업로드: 순수 HTML 폼 제출이 아니라 자바스크립트의 fetch나 XMLHttpRequest, FormData 객체를 통해 파일을 전송할 때는 <form> 태그의 HTML 속성이 직접 반영되지 않으므로 요청 본문 구성 방식을 별도로 점검해야 합니다.

참고 자료와 확인 범위

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

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