HTML-сущности: как декодировать спецсимволы в тексте
Узнайте, что такое HTML-сущности (&, <, "), когда их использовать и как быстро конвертировать текст с символами
Открываете страницу — а там вместо кавычек ", вместо амперсанда &, вместо угловых скобок < и >. Или наоборот: вставили текст из базы данных, а браузер интерпретирует его как HTML-код и ломает вёрстку. Всё это — HTML-сущности, и с ними придётся разбираться каждому, кто работает с текстом в вебе.
Что такое HTML-сущности
HTML-сущности (HTML entities) — это специальные последовательности символов, которые браузер преобразует в нужный символ при отображении. Они начинаются с амперсанда & и заканчиваются точкой с запятой ;.
Например:
&→&<→<>→>"→"'→' → неразрывный пробел
Существует два типа сущностей:
- Именованные (named entities):
©для ©,€для € - Числовые (numeric entities):
©или©для того же ©
Зачем они нужны
HTML использует угловые скобки и амперсанды для собственных целей. Если написать в коде <script>, браузер попытается выполнить это как JavaScript. Если нужно показать именно текст <script>, приходится экранировать:
<script>alert('XSS')</script>
Три главных сценария использования:
Безопасность. Защита от XSS-атак. Пользователь вводит в форму <img src=x onerror=alert(1)>, а вы перед выводом конвертируете в <img src=x onerror=alert(1)> — и злонамеренный код превращается в безобидный текст.
Отображение спецсимволов. Нужно показать знак авторских прав ©, евро € или стрелку →? Не все редакторы удобны для ввода таких символов, проще использовать ©, €, →.
Совместимость кодировок. Если страница в ASCII, а нужно вывести кириллицу или китайские иероглифы, можно использовать числовые сущности: П для буквы «П».
Кодирование vs декодирование
Кодирование (encoding) — превращаем обычные символы в сущности:
Вход: <div class="text">Hello & goodbye</div>
Выход: <div class="text">Hello & goodbye</div>
Это делают перед вставкой пользовательского текста в HTML. В PHP есть htmlspecialchars(), в JavaScript — методы вроде создания текстового узла через document.createTextNode().
Декодирование (decoding) — обратный процесс:
Вход: <div>Hello & goodbye</div>
Выход: <div>Hello & goodbye</div>
Нужно при чтении данных из базы, парсинге API-ответов, работе с RSS-лентами.
Как декодировать в JavaScript
Браузер умеет декодировать сущности сам — можно этим воспользоваться. Создаём временный элемент, кладём туда закодированный текст и читаем:
function decodeHTML(text) {
const textarea = document.createElement('textarea');
textarea.innerHTML = text;
return textarea.value;
}
const encoded = 'AT&T, <script>';
const decoded = decodeHTML(encoded);
console.log(decoded); // AT&T, <script>
Используем textarea, потому что он не выполняет скрипты и не рендерит HTML — безопаснее, чем div.
В Node.js (без DOM) можно взять библиотеку he или модуль html-entities:
const {decode} = require('html-entities');
console.log(decode('<p>Hello & goodbye</p>'));
// <p>Hello & goodbye</p>
Как кодировать: базовые правила
Кодируйте как минимум пять символов:
&→&<→<>→>"→"'→'или'
В JavaScript это можно сделать через замену:
function encodeHTML(text) {
return text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
Или через API браузера:
function encodeHTML(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
В серверных языках используйте встроенные функции:
- PHP:
htmlspecialchars($text, ENT_QUOTES, 'UTF-8') - Python:
html.escape(text) - Ruby:
CGI.escapeHTML(text)
Частые ошибки и как их избежать
Двойное кодирование. Если закодировать текст дважды, получится &amp; вместо &. При выводе браузер покажет & вместо &. Проверяйте, не был ли текст уже обработан.
Забытый амперсанд. Пишете AT&T в коде — рискуете, что браузер попытается интерпретировать как сущность. Всегда кодируйте & в &, даже если за ним не следует валидная сущность.
Кодирование внутри атрибутов. В атрибутах действуют те же правила:
<a href="page.php?foo=1&bar=2">Link</a>
<img alt=""Цитата"">
Использование неправильной функции. Функции вроде urlencode() в PHP — для URL, а не для HTML. Для HTML нужен htmlspecialchars().
Инструменты для работы с сущностями
Вручную конвертировать текст утомительно, особенно если работаете с большими объёмами или сложными данными. В этом помогут специализированные инструменты.
Декодер HTML-сущностей превращает <div> обратно в <div> за секунду — просто вставьте текст и получите результат. Полезно при отладке API, парсинге фидов или работе с легаси-базами данных.
Для обратной задачи — кодирования спецсимволов — пригодится Энкодер HTML-сущностей. Вставляете текст с амперсандами и кавычками, получаете безопасную версию для вывода в HTML.
Оба инструмента работают прямо в браузере, не отправляют данные на сервер и поддерживают все стандартные сущности HTML5.