HTML 엔티티 변환
텍스트를 HTML 안에서 안전하도록 이스케이프하고, 이름·숫자 문자 참조를 원래 문자로 되돌립니다.
결과가 여기에 표시됩니다
이 도구가 하는 일
HTML에는 텍스트로 뜻한 미만 기호와 태그를 여는 미만 기호를 구별할 방도가 없습니다. 이 언어는 그것을 엔티티로 해결합니다: 마크업으로 읽히지 않으면서 문자를 나타내는 짧은 이스케이프 나열입니다. 이 도구는 양방향으로 변환합니다 — 맨 텍스트를 그 이스케이프 형태로, 그리고 이스케이프된 HTML을 그것이 나타내는 문자로 되돌립니다.
두 방향 모두 전적으로 브라우저 안에서 돕니다. 사람이 엔티티 디코더에 붙여넣는 텍스트는 대개 스크레이핑한 페이지, 고객 메일, 뜻을 헤아리려는 데이터베이스 열이라, 여기서는 대부분의 도구보다 그것이 더 중요합니다.
중요한 다섯 문자
수천 개의 엔티티가 있지만 텍스트를 안전하게 하는 데 필요한 것은 한 줌뿐입니다. 여기서 인코딩은 정확히 다섯 문자를 바꾸고 그 밖은 모두 읽을 수 있게 둡니다:
- 앰퍼샌드는 &가 됩니다 — 이것을 먼저. 아니면 다른 모든 치환 자체가 다시 엔티티로 읽힙니다.
- 미만 기호는 <가 됩니다 — 태그를 시작할 수 있는 문자입니다.
- 초과 기호는 >가 됩니다 — 혼자서는 덜 위험하지만 대칭을 위해, 또 부주의한 파서를 살아남기 위해 이스케이프합니다.
- 큰따옴표는 "가 됩니다 — 큰따옴표로 쓴 속성값 안에서 필요합니다.
- 아포스트로피는 '가 됩니다 — 작은따옴표로 쓴 속성값 안에서 필요합니다.
마지막 것은 일부러 숫자로 쓰였습니다. 그것을 가리키는 이름 '도 있지만 XML에서 왔고 HTML 4는 결코 정의하지 않아, 오래된 파서는 그것을 문자 그대로의 텍스트로 통과시키고 이스케이프가 조용히 실패합니다. 숫자 형태는 늘 어디서나 통했고, 그래서 제대로 된 이스케이프 라이브러리가 그것을 냅니다.
이름, 10진수, 16진수
어떤 문자든 세 방식으로 쓸 수 있고, 디코딩은 그 모두를 받습니다. em 대시가 좋은 예입니다:
named — 읽을 수 있는 형태, 다만 이름이 있는 문자에만 decimal — 10진수로 된 코드 포인트 hex — 같은 코드 포인트를 16진수로, 유니코드 표가 쓰는 표기
이 도구는 디코딩할 때 HTML 4 집합의 255개 이름을 인식합니다 — Latin-1 글자, 그리스 문자, 화살표, 수학 기호, 활자 약물로, 그것들만으로 실제 텍스트에 나타나는 거의 모든 것을 덮습니다. HTML 5는 약 2200개를 더 정의하지만 거의 모두 난해한 수학 기호입니다. 그 표를 지니면 대부분의 문서가 결코 쓰지 않는 이름과 맞바꿔 모든 페이지 로드에 수십 킬로바이트를 더하게 됩니다. 집합 밖의 이름은 떨구지 않고 보고되므로, 대가는 경고이지 결코 오답이 아닙니다.
인코딩은 반대 방향이고 일부러 맨 그대로입니다: 위의 다섯 문자에는 이름을, 그 밖 모두에는 10진수를 씁니다. 문자 자체가 UTF-8 문서에서 흠 없이 유효할 때 그것이 …나 ’로 바뀌는 일은 없습니다.
이스케이프는 하나의 규칙이 아니라 넷
엔티티 이스케이프를 인젝션에 대한 답으로 다루고 싶어지고, 요소 내용 안에서는 정말 그렇습니다. 하지만 HTML은 사실 서로 중첩된 네 언어이고, 저마다 규칙이 있습니다. 엔티티 이스케이프는 이 중 처음 둘에서는 옳고 나머지에서는 쓸모없습니다:
- 요소 내용 — 태그 사이의 텍스트. 엔티티 이스케이프가 바로 옳습니다.
- 따옴표 붙은 속성값. 속성이 정말 따옴표로 감싸였다면 엔티티 이스케이프가 옳습니다. 따옴표가 없으면 값 속 공백이 속성을 끝내고 이스케이프는 아무것도 주지 못합니다.
- 스크립트 블록 안. 엔티티가 아니라 JavaScript 문자열 이스케이프가 적용됩니다 — 브라우저가 거기서 엔티티를 디코딩하지 않으므로 이스케이프된 따옴표가 문자 그대로의 문자 "로 도착합니다.
- href나 src 같은 URL 속성. 엔티티 이스케이프는 javascript: URL을 막지 못합니다. 위험이 스킴에 있지 엔티티가 바꿀 어떤 문자에도 있지 않기 때문입니다.
실무 규칙: 텍스트가 문서에 삽입되는 지점에서, 그것이 착지하는 바로 그 문맥의 규칙을 써서 이스케이프하세요 — 나중에 어디서나 통하기를 바라며 일찍 한 번이 아니라.
때때로 &amp;를 보는 이유
이것이 엔티티 디코더에 손을 뻗는 가장 흔한 이유입니다. 텍스트가 이스케이프되고 나서 또 이스케이프된 것입니다 — 대개 한 번은 애플리케이션 코드가, 또 한 번은 출력을 이미 이스케이프하는 템플릿 엔진이나 프레임워크가:
original Fish & Chips escaped Fish & Chips 표시: Fish & Chips escaped x2 Fish &amp; Chips 표시: Fish & Chips
디코딩은 정확히 한 겹을 벗기므로, 한 번 돌리면 어느 경우인지 알 수 있습니다. 출력에 아직 엔티티가 있으면 겹이 여럿이었던 것입니다. 고치는 법은 거의 결코 표시할 때 엔티티를 벗기는 것이 아니라 — 중복된 이스케이프 단계를 찾아 없애는 것입니다. 같은 버그가 저장된 데이터를 조용히 망가뜨리고 있기 때문입니다.
비ASCII와 그것을 위한 옵션
UTF-8로 제공되는 페이지는 악센트 글자, 한국어, 아랍어, 중국어, 이모지에 엔티티가 필요 없습니다. 그 문자들은 그대로 유효하고, 읽을 수 있게 두면 소스가 읽기 쉽고 파일이 더 작아집니다. 여기서 그것이 기본값입니다.
이 옵션이 있는 것은 일부 목적지가 지금도 맨 ASCII를 고집하기 때문입니다: 오래된 메일 템플릿, 127을 넘는 바이트를 망가뜨리는 시스템, 또는 아무도 인코딩을 바꾸려 하지 않는 데이터베이스 열입니다. 켜면 그런 문자를 모두 10진수 참조로 씁니다 — é는 é, 가는 가가 됩니다.
이모지는 한마디 할 만합니다. 이모지는 그 코드 포인트 전체에 대해 하나의 참조로 쓰입니다. 예를 들어 🙂이고, 결코 두 반쪽으로가 아닙니다. JSON 이스케이프 도구를 써 봤다면 이것은 거기서 일어나는 것의 반대입니다. 거기서는 형식이 이모지를 두 개의 \u 이스케이프로 나누기를 특별히 요구합니다. 같은 문자, 두 개의 옳은 답입니다. 두 형식이 서로 다른 단위로 이스케이프를 정의하기 때문입니다.
참조를 디코딩할 수 없을 때
여기서 디코딩은 결코 실패하지 않고 아무것도 지우지 않습니다. 해석할 수 없는 참조는 찾은 그대로 남아 그 줄·열과 함께 출력 위에 나열됩니다. 세 가지가 보고됩니다:
- &nbps; 같은 알 수 없는 이름 — 거의 늘 의 오타입니다. 이것이 대응할 만한 경고입니다: 내용에서 공백이 빠졌는데 아무도 눈치채지 못했다는 뜻입니다.
- �이나 유니코드 범위를 넘은 값 같은, 문자가 아닌 숫자. 디코딩할 대상이 없으므로 텍스트로 남습니다.
- 128과 159 사이의 숫자. 아래 참조.
외톨이 앰퍼샌드는 아예 보고되지 않습니다. HTML에서 R&D와 Q&A는 보통 텍스트이고, 떠도는 앰퍼샌드를 모두 오류로 다루면 중요한 경고가 산문의 잡음에 묻힙니다.
128부터 159 범위는 진짜 기이한 것입니다. 그 숫자들은 아무도 쓸 뜻이 없는 보이지 않는 제어 문자를 가리킵니다. 문서가 Windows-1252로 작성되어 나타나는 것으로, 거기서는 같은 숫자가 둥근 따옴표, 대시, 유로 기호입니다. 브라우저는 바로 그 이유로 그것들을 조용히 Windows-1252로 읽고, 이 도구도 그 동작에 맞춰 결과가 페이지가 실제로 표시할 것과 같게 합니다 — 다만 경고로 그렇게 알립니다. 청하지 않은 조용한 치환은 요란한 것보다 나쁘기 때문입니다.
자주 묻는 질문
- 이 다섯 문자를 이스케이프하면 XSS를 막기에 충분한가요?
- 요소 내용과 따옴표 붙은 속성값 안에서라면 그렇습니다 — 바로 그것을 위한 것입니다. 스크립트나 스타일 블록 안, 따옴표 없는 속성, href 같은 URL 속성 안에서는 충분하지 않고, 저마다 이스케이프 규칙이 필요합니다. 이스케이프는 텍스트의 성질이 아니라 텍스트가 착지하는 곳의 성질입니다.
- 아포스트로피가 '가 아니라 '로 인코딩되는 이유는 무엇인가요?
- '는 HTML 4가 결코 정의하지 않은 XML 엔티티이기 때문입니다. HTML 5 이전의 파서는 그것을 문자 그대로의 텍스트로 남겨, 이스케이프했다고 여긴 아포스트로피가 그렇지 않게 됩니다. 숫자 형태는 어느 파서에서나 통하므로 안전한 기본값입니다.
- 제 페이지가 앰퍼샌드 대신 &amp;를 표시합니다. 무슨 일인가요?
- 텍스트가 두 번 이스케이프됐습니다. 여기서 디코딩해 보세요: 한 번에 &amp;가 &가 되어 여분의 겹을 확인해 줍니다. 텍스트가 아니라 파이프라인을 고치세요 — 대개 당신의 코드가 템플릿 엔진이 이미 이스케이프하던 출력을 이스케이프합니다.
- 한국어, 아랍어, 이모지를 인코딩해야 하나요?
- UTF-8로 제공되는 현대 페이지에는 필요 없습니다. 그대로 유효합니다. 비ASCII 옵션은 오래된 메일 템플릿처럼 하류의 무언가가 맨 ASCII를 고집할 때만 켜세요. 그러면 각 이모지가 하나의 숫자 참조로 쓰입니다.
- “을 잘 디코딩했는데도 도구가 경고하는 이유는 무엇인가요?
- 147이 당신이 보는 따옴표가 아니라 보이지 않는 제어 문자를 가리키기 때문입니다. 그것을 쓰는 문서는 Windows-1252로 작성되었고, 거기서 147은 둥근 따옴표입니다 — 브라우저가 그렇게 읽고 이 도구도 그렇게 합니다. 경고는 치환이 일어났음을 알려, 소스 인코딩이 고칠 수 있는 것이라면 고칠 수 있게 합니다.
- 제 텍스트가 어딘가로 전송되나요?
- 아니요. 인코딩도 디코딩도 전적으로 브라우저 안에서 돕니다. 붙여넣은 내용이 기기 밖으로 나가지 않습니다.