폼 전송 시 입력값이 서버로 전달되지 않을 때: disabled와 readonly 차이

폼 전송 시 입력값이 서버로 넘어가지 않는 증상

웹 화면에서 회원 아이디, 계정 식별자, 주문 번호처럼 사용자가 임의로 고치면 안 되는 필드를 화면에 표시한 뒤 양식을 제출했을 때, 서버 측 수신 데이터에 해당 항목이 아예 들어오지 않는 문제가 자주 발생합니다. 화면에는 값이 정상적으로 적혀 있고 오류 표시도 뜨지 않지만, 백엔드 컨트롤러나 네트워크 요청 파라미터에는 키 자체가 누락되어 공백이나 null 처리되는 현상입니다.

이러한 현상은 사용자의 편집을 막기 위해 입력 요소에 disabled 속성을 지정했을 때 발생합니다. 버튼 클릭 시 페이지가 새로고침되는 원인을 점검할 때처럼 HTML 폼 컨트롤의 명세상 기본 동작 방식을 명확히 구분하지 않으면, 브라우저가 전송 대상에서 컨트롤을 배제하는 규칙을 예상치 못하게 마주하게 됩니다.

disabled와 readonly의 폼 제출 동작 차이

HTML 명세에서 disabled 속성과 readonly 속성은 사용자의 값 변경을 제한한다는 공통점이 있지만, 폼 제출과 브라우저 상호작용 측면에서는 완전히 다르게 동작합니다.

항목disabled 속성readonly 속성
서버 전송 여부폼 제출 시 데이터가 전송되지 않음폼 제출 시 키와 값이 정상 전송됨
초점(Focus) 이동키보드나 마우스로 초점을 받을 수 없음초점 이동 및 텍스트 선택이 가능함
유효성 검사제약 조건 검증(Constraint Validation) 제외제약 조건 검증 제외
지원 요소input, select, textarea, button 등텍스트 계열 input, textarea

MDN disabled 속성 문서에 따르면 불리언 속성인 disabled가 적용된 요소는 브라우저 이벤트나 초점을 받지 못하며 폼이 제출될 때 함께 전송되지 않습니다. 반면 MDN readonly 속성 문서에 명시된 readonly 속성은 사용자의 직접 수정을 막지만 요소 자체가 활성 컨트롤로 남아 폼 제출 시 해당 값이 서버로 전송됩니다.

재현: <form action="/submit"><input type="text" name="user_id" value="admin" disabled><button type="submit">전송</button></form> 실행 후 전송하면 disabled 필드는 성공한 컨트롤로 간주되지 않아 요청 본문이나 쿼리스트링에서 user_id 항목 자체가 완전히 누락됩니다. 해결: 사용자의 수정을 막으면서 값은 서버로 보내야 할 경우 disabled 대신 <input type="text" name="user_id" value="admin" readonly> 속성을 적용합니다. 결과: 사용자의 값 수정은 방지되면서 전송 시 user_id=admin 파라미터가 온전하게 전달됩니다.

수정 방지와 전송 유지를 위한 교체 점검 순서

사용자 수정을 방지하면서 서버로 데이터를 전송해야 할 때는 다음 순서로 코드를 점검하고 수정합니다.

  1. 누락된 파라미터 확인: 네트워크 탭이나 서버 로그를 확인하여 양식 전송 시 빠진 입력 필드의 name 속성을 파악합니다.
  2. disabled 속성 제거: 해당 입력 요소에 disabled가 단독으로 적용되어 있거나 상위 fieldset 요소로부터 비활성화 상태를 상속받고 있는지 확인하고 이를 제거합니다.
  3. readonly 속성 추가: 값을 보존하며 변경만 차단해야 하는 필드에 readonly 속성을 부여합니다.
  4. 폼 제출 재시도: 브라우저에서 값을 직접 수정할 수 없는지 확인한 뒤 양식을 제출하여 쿼리스트링이나 요청 본문에 값이 전달되는지 점검합니다.

아래는 변경 전과 변경 후의 전형적인 입력 필드 형태입니다.

<!-- 잘못된 예: 서버 전송 시 user_id 항목 누락 -->
<input type="text" name="user_id" value="admin" disabled>

<!-- 올바른 예: 값 수정은 차단되고 user_id=admin 전송 유지 -->
<input type="text" name="user_id" value="admin" readonly>

readonly를 쓸 수 없는 입력 유형과 주의점

readonly 속성을 적용할 때는 지원되는 입력 요소의 유형을 반드시 확인해야 합니다. 텍스트 입력창(type="text", email, password, number 등)과 <textarea>는 readonly를 지원하지만, 다음과 같은 요소에는 적용되지 않습니다.

  • 드롭다운 메뉴(<select>): select 태그에는 readonly 속성이 유효하지 않습니다. 여기에 disabled를 주면 선택값 자체가 전송되지 않습니다.
  • 선택형 컨트롤(checkbox, radio): 체크박스와 라디오 버튼 역시 readonly 속성을 지원하지 않습니다.
  • 버튼 및 파일 첨부: button 요소나 type="file" 입력 요소도 읽기 전용 속성이 적용되지 않습니다. 파일 전송 시의 인코딩 규칙은 폼 첨부 파일 전송 설정을 별도로 확인해야 합니다.
  • required 속성과의 관계: disabled나 readonly가 선언된 입력 필드에는 required 속성이 효력을 갖지 않으며 명세상 함께 사용하는 것이 허용되지 않습니다.

이 점검 방법으로 확인하기 어려운 영역과 한계

입력 필드를 readonly로 전환하는 작업은 순수 브라우저 UI 수준에서 일반 사용자의 타이핑 입력을 막는 조치일 뿐입니다. 다음 영역은 이 방법만으로 보장할 수 없습니다.

  • 클라이언트 측 임의 변조 방지: 브라우저 개발자 도구를 이용하면 readonly 속성을 임의로 지우거나 스크립트를 통해 입력값을 변경한 뒤 제출할 수 있습니다. 중요한 식별자나 권한 정보는 클라이언트 폼 값에 의존하지 않고 서버 세션이나 데이터베이스 권한 검증을 통해 처리해야 합니다.
  • 스타일 가시성: 브라우저는 disabled 요소를 기본적으로 흐리게 회색조로 표현하지만, readonly 요소는 기본 텍스트 상자와 시각적으로 유사하게 렌더링할 수 있습니다. 사용자가 편집 가능 여부를 식별할 수 있는지는 화면 디자인 측면에서 별도로 확인해야 합니다.
  • 상위 fieldset 비활성화: 개별 입력 필드에서 disabled를 지우더라도 부모 <fieldset disabled> 태그가 비활성화되어 있다면 내부 요소는 여전히 폼 제출 대상에서 제외됩니다.

참고 자료와 확인 범위

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

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