블로그나 기술 문서를 작성하다 보면 <p>나 <div>, <script> 같은 태그를 화면에 예제 코드로 보여주어야 할 때가 있다. 하지만 코드를 본문에 그대로 입력하면 브라우저가 이를 마크업으로 해석해 태그가 사라지고 레이아웃이 깨지거나 스타일이 의도치 않게 적용된다. 텍스트로 보여야 할 태그가 화면에서 증발하거나 실행되는 현상은 웹 개발 입문자와 블로거가 자주 마주치는 문제다. 브라우저의 파싱 원리를 이해하고 특수문자를 HTML 엔티티로 변환하면 단 몇 초 만에 해결할 수 있다.
왜 이 문제가 생기는가
브라우저는 웹문서를 읽을 때 HTML 파서를 통해 위에서부터 차례대로 코드를 분석한다. 이 과정에서 꺾쇠괄호(< >)를 만나면 이를 일반 텍스트가 아니라 화면을 구성하는 HTML 태그의 시작과 끝으로 인식한다. 따라서 작성자가 단순히 글자로 적어 둔 태그라도 브라우저 입장에서는 렌더링해야 할 실제 마크업 요소로 처리하게 된다.
HTML 표준에서는 문법 구조를 정의하기 위해 특정 기호들을 예약 문자(Reserved Characters)로 지정하고 있다. 대표적인 예약 문자는 다음과 같다.
| 특수문자 | 명칭 | 기능 | 엔티티 명칭(Named) |
|---|---|---|---|
< | Less Than | 태그의 시작 선언 | < |
> | Greater Than | 태그의 종료 선언 | > |
& | Ampersand | 엔티티 코드의 시작 선언 | & |
" | Double Quote | 속성값의 시작과 끝 지정 | " |
' | Single Quote | 속성값의 시작과 끝 지정 | ' |
태그가 그대로 실행되는 현상은 화면 구성의 훼손에 그치지 않고 심각한 보안 취약점으로 직결된다. 게시판이나 댓글 창처럼 사용자 입력을 받는 곳에서 특수문자를 치환하지 않고 출력하면, 악의적인 사용자가 삽입한 <script> 태그가 방문자의 브라우저에서 강제로 실행될 수 있다. 이를 크로스 사이트 스크립팅(XSS, Cross-Site Scripting) 공격이라 부른다. XSS 공격이 발생하면 관리자 권한 탈취, 세션 하이재킹, 악성 사이트 리다이렉션 같은 피해가 따른다. 따라서 HTML 태그를 온전한 텍스트 형태로 출력하고 웹사이트를 안전하게 지키려면 예약 문자를 반드시 HTML 엔티티로 치환(이스케이프)해야 하며, HTML 특수문자 처리 자가진단 체크리스트를 통해 보안 취약점을 미리 점검하는 것이 중요하다.
해결 방법
HTML 엔티티 변환 도구 사용 순서
- 1변환할 코드 입력
화면에 출력할 HTML 태그나 소스코드를 복사하여 변환기 입력창에 붙여넣는다.
- 2변환 범위와 출력 포맷 설정
5대 핵심 예약 문자 또는 전체 변환 범위를 선택하고 Named, 10진수, 16진수 중 출력 포맷을 지정한다.
- 3변환 결과 복사 및 적용
생성된 엔티티 코드를 복사하여 블로그 HTML 편집 모드나 소스코드 파일의 출력 영역에 붙여넣는다.
수많은 태그와 특수문자가 섞인 긴 코드를 수작업으로 일일이 치환하면 오탈자가 발생하기 쉽다. 이때는 전용 변환 도구를 활용하여 코드를 일괄 치환하는 것이 가장 빠르고 정확하다.
1단계: 변환할 코드 입력하기
화면에 출력하고자 하는 HTML 태그나 소스코드를 복사한 다음 HTML 엔티티 변환기 입력창에 붙여넣는다. 텍스트를 입력하는 즉시 브라우저 로컬 엔진이 실시간으로 입력값을 감지한다.
2단계: 변환 범위와 출력 포맷 설정하기
작업 목적에 맞춰 상단 옵션 패널에서 변환 스코프를 선택한다. 보안 방어를 위해 5대 핵심 예약 문자만 빠르게 치환할지, 다국어 문자와 유니코드 기호까지 전체 변환할지 결정한다. 또한 결과물 형태를 가독성이 좋은 문자 포맷(<)인 Named 모드로 둘지, 시스템 호환성을 위한 10진수(Decimal) 또는 16진수(Hex) 모드로 변경할지 클릭하여 지정한다. 옵션을 클릭하면 하단 미리보기 영역에 변환된 엔티티 코드가 실시간으로 반영된다.
3단계: 변환된 결과 복사 및 웹문서 적용
변환창 우측의 복사 버튼을 눌러 생성된 엔티티 코드를 클립보드에 담는다. 그런 다음 글을 작성 중인 블로그 관리자 페이지의 HTML 편집 모드나 소스코드 파일의 출력 영역에 코드를 붙여넣는다. 웹페이지를 새로고침하면 태그가 실행되거나 사라지지 않고 작성한 구문 그대로 브라우저 화면에 텍스트로 나타난다.
코드 예제를 화면에 배치할 때는 변환된 텍스트를 <pre><code> 태그 블록으로 감싸는 방식을 권장한다. HTML 엔티티 변환으로 태그 실행을 차단하고, <pre><code> 태그로 들여쓰기와 고정폭 글꼴을 유지하면 실제 개발 환경과 동일한 깔끔한 코드 박스를 만들 수 있다.
그래도 안 될 때
마크다운 파서가 입력된 엔티티 코드를 디코딩한 후 다시 렌더링함
엔티티 변환 대신 백틱 3개(```)로 감싸는 마크다운 코드 블록 기능을 사용한다.
웹 브라우저가 연속된 공백 문자를 하나로 축약하여 표시함
CSS 스타일에 white-space: pre-wrap; 속성을 추가하거나 감싸는 태그를 <pre>로 변경한다.
이미 치환된 코드의 & 기호가 한 번 더 변환되어 이중 이스케이프가 발생함
원본 텍스트를 확인하고 중복 인코딩된 부분을 디코딩하여 단일 엔티티 상태로 되돌린다.
변환을 마친 코드를 적용했음에도 화면에 정상적으로 출력되지 않는다면 다음 예외 원인을 확인해야 한다.
마크다운 에디터의 자동 디코딩 현상
티스토리, 벨로그, 깃허브 등 마크다운을 지원하는 플랫폼 중 일부는 본문에 입력된 <를 마크다운 파서가 일반 텍스트 문자로 디코딩한 뒤 다시 렌더링을 시도한다. 이 과정에서 다시 일반 < 기호로 환원되어 태그가 사라지는 문제가 생긴다. 이런 환경에서는 엔티티 변환 대신 백틱 3개(```)로 감싸는 마크다운 코드 블록 기능을 쓰는 편이 적합하다.
연속 공백과 줄바꿈이 한 칸으로 축소되는 현상
태그 자체는 화면에 잘 나오지만 코드의 들여쓰기와 줄바꿈이 모두 무시되고 한 줄로 길게 늘어지는 경우가 있다. 웹 브라우저는 연속된 공백 문자를 하나로 축약하여 표시하기 때문이다. 출력 영역을 감싸는 CSS 스타일에 white-space: pre-wrap; 속성을 추가하거나 감싸는 태그를 <pre>로 변경하여 공백 서식을 유지해야 한다.
엔티티 기호의 이중 이스케이프(Double Escaping)
화면에 의도한 <div> 대신 <div>라는 영문 기호 자체가 그대로 찍히는 경우가 있다. 이미 엔티티로 치환된 코드의 & 기호를 웹 에디터나 변환기가 한 번 더 변환하여 &lt;div&gt;로 만들었기 때문이다. 이럴 때는 원본 텍스트를 다시 확인하고, 중복 인코딩된 부분을 디코딩하여 단일 엔티티 상태로 되돌려야 한다.
재발 방지 팁
HTML 태그 출력 오류와 화면 깨짐을 사전에 차단하기 위한 작업 습관을 소개한다.
프론트엔드 개발 시 안전한 텍스트 바인딩 적용
자바스크립트로 웹 요소를 동적으로 화면에 그릴 때는 innerHTML 대신 textContent 속성을 사용한다. React의 중괄호({}) 표현식이나 Vue의 v-text 디렉티브를 활용하면 프레임워크 수준에서 텍스트 내부의 특수문자를 브라우저가 알아서 안전하게 처리하므로 태그 오작동과 XSS 위험을 원천적으로 막을 수 있다.
자주 사용하는 코드 스니펫 템플릿화
기술 블로그나 매뉴얼 문서를 정기적으로 작성한다면 자주 쓰는 HTML 구문의 엔티티 변환본을 스니펫(Snippet)으로 미리 저장해 둔다. 매번 태그를 수동으로 타이핑하지 않고 템플릿을 불러와 사용하면 오탈자로 인한 문법 오류를 크게 줄일 수 있다.
브라우저 개발자 도구(DevTools)로 렌더링 검사
문서 작성을 마친 후에는 웹 브라우저의 개발자 도구(F12)를 열어 Elements 탭을 확인한다. 화면에 보이는 코드가 실제 DOM 엘리먼트로 삽입되었는지, 아니면 순수 텍스트 노드로 안전하게 위치하고 있는지 점검하는 습관을 들이면 렌더링 문제를 빠르게 포착할 수 있다.