Escape HTML с помощью jQuery
Я придумал взломать HTML-код с помощью jQuery, и мне интересно, видит ли кто-нибудь проблему с ним.
$('<i></i>').text(TEXT_TO_ESCAPE).html();
Тег <i>
- это просто фиктивный код, так как jQuery нужен контейнер для установки текста.
Есть ли более простой способ сделать это? Обратите внимание, что мне нужен текст, хранящийся в переменной, а не для отображения (иначе я мог бы просто позвонить elem.text(TEXT_TO_ESCAPE);
).
Спасибо!
Ответы
Ответ 1
Это довольно стандартный способ сделать это, моя версия использовала <div>
хотя:
return $('<div/>').text(t).html();
Это не технически безопасно на 100%, хотя Майк Самуэль отмечает, но на практике это довольно безопасно.
Текущий Prototype.js делает следующее:
function escapeHTML() {
return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
}
Но он использовал для использования "положить текст в div и извлечь HTML" трюк.
Там также _.escape
в Underscore, что делает это следующим образом:
// List of HTML entities for escaping.
var htmlEscapes = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/'
};
// Regex containing the keys listed immediately above.
var htmlEscaper = /[&<>"'\/]/g;
// Escape a string for HTML interpolation.
_.escape = function(string) {
return ('' + string).replace(htmlEscaper, function(match) {
return htmlEscapes[match];
});
};
Это почти тот же подход, что и Prototype. Большинство JavaScript, которые я делаю в последнее время, имеют Underscore, поэтому я использую _.escape
в эти дни.
Ответ 2
Нет гарантии, что html()
будет полностью экранирован, поэтому после конкатенации результат может быть небезопасным.
html()
основан на innerHTML
, и браузер может, не нарушая много ожиданий, реализовать innerHTML
, чтобы $("<i></i>").text("1 <").html()
был "1 <"
, а $("<i></i>").text("b>").html()
- "b>"
.
Затем, если вы соедините эти два индивидуально безопасных результата, вы получите "1 <b>"
, который, очевидно, не будет HTML-версией конкатенации двух частей открытого текста.
Таким образом, этот метод небезопасен путем вычитания из первых принципов, и нет широко используемого спецификатора innerHTML
(хотя HTML5 обращается к нему).
Лучший способ проверить, делает ли он то, что вы хотите, - это проверить такие угловые случаи, как это.
Ответ 3
Это должно сработать. Это в основном, как это делает библиотека Prototype.js, или, по крайней мере, как это было сделано для этого. Обычно я делаю это с тремя вызовами ".replace()", но это в основном просто привычка.