Escape HTML, используя jQuery
Я придумал способ избежать HTML, используя jQuery, и мне интересно, видит ли кто-нибудь проблему с ним.
$('<i></i>').text(TEXT_TO_ESCAPE).html();
<i>
Это просто пустышка, так как jQuery нужен контейнер для установки текста.
Возможно, есть более простой способ сделать это? Обратите внимание, что мне нужен текст, хранящийся в переменной, а не для отображения (в противном случае я мог бы просто вызвать elem.text(TEXT_TO_ESCAPE);
).
Спасибо!
3 ответа
Это довольно стандартный способ сделать это, моя версия использовала <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
Эти дни.
Там нет никакой гарантии, что html()
будет полностью экранирован, поэтому результат может быть небезопасным после объединения.
html()
основывается на innerHTML
и браузер может, не нарушая много ожиданий, реализовать innerHTML
чтобы $("<i></i>").text("1 <").html()
является "1 <"
и что $("<i></i>").text("b>").html()
является "b>"
,
Затем, если вы объедините эти два индивидуально безопасных результата, вы получите "1 <b>"
которая, очевидно, не будет HTML-версией объединения двух частей открытого текста.
Таким образом, этот метод небезопасен из-за выведения из первых принципов, и нет innerHTML
(хотя HTML5 действительно решает эту проблему).
Лучший способ проверить, выполняет ли он то, что вам нужно, - это протестировать подобные случаи.
Это должно работать. Это в основном то, как это делает библиотека Prototype.js, или, по крайней мере, как это было раньше. Я обычно делаю это с помощью трех вызовов ".replace()", но это в основном просто привычка.