폼 전송 시 입력값이 서버로 전달되지 않을 때: 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 파라미터가 온전하게 전달됩니다.수정 방지와 전송 유지를 위한 교체 점검 순서
사용자 수정을 방지하면서 서버로 데이터를 전송해야 할 때는 다음 순서로 코드를 점검하고 수정합니다.
- 누락된 파라미터 확인: 네트워크 탭이나 서버 로그를 확인하여 양식 전송 시 빠진 입력 필드의
name속성을 파악합니다. - disabled 속성 제거: 해당 입력 요소에
disabled가 단독으로 적용되어 있거나 상위fieldset요소로부터 비활성화 상태를 상속받고 있는지 확인하고 이를 제거합니다. - readonly 속성 추가: 값을 보존하며 변경만 차단해야 하는 필드에
readonly속성을 부여합니다. - 폼 제출 재시도: 브라우저에서 값을 직접 수정할 수 없는지 확인한 뒤 양식을 제출하여 쿼리스트링이나 요청 본문에 값이 전달되는지 점검합니다.
아래는 변경 전과 변경 후의 전형적인 입력 필드 형태입니다.
<!-- 잘못된 예: 서버 전송 시 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 · 오류를 발견하면 이 글의 오류 신고로 알려주세요.