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,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}

Но раньше он использовал трюк "положить текст в div и извлечь HTML".

Есть также _.escape в Underscore, это делает это так:

// List of HTML entities for escaping.
var htmlEscapes = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#x27;',
  '/': '&#x2F;'
};

// 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()", но это в основном просто привычка.

Другие вопросы по тегам