Экранирование строк HTML с помощью jQuery - PullRequest
573 голосов
/ 24 августа 2008

Кто-нибудь знает простой способ экранирования HTML из строк в jQuery ? Мне нужно иметь возможность передавать произвольную строку и правильно экранировать ее для отображения на странице HTML (предотвращая атаки с использованием JavaScript / HTML-инъекций). Я уверен, что для этого можно расширить jQuery, но в настоящий момент я недостаточно разбираюсь в фреймворке, чтобы этого добиться.

Ответы [ 24 ]

565 голосов
/ 20 августа 2012

Существует также решение от mustache.js

var entityMap = {
  '&': '&',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#39;',
  '/': '&#x2F;',
  '`': '&#x60;',
  '=': '&#x3D;'
};

function escapeHtml (string) {
  return String(string).replace(/[&<>"'`=\/]/g, function (s) {
    return entityMap[s];
  });
}
421 голосов
/ 24 августа 2008

Поскольку вы используете jQuery , вы можете просто установить свойство элемента text:

// before:
// <div class="someClass">text</div>
var someHtmlString = "<script>alert('hi!');</script>";

// set a DIV's text:
$("div.someClass").text(someHtmlString);
// after: 
// <div class="someClass">&lt;script&gt;alert('hi!');&lt;/script&gt;</div>

// get the text in a string:
var escaped = $("<div>").text(someHtmlString).html();
// value: 
// &lt;script&gt;alert('hi!');&lt;/script&gt;
180 голосов
/ 17 декабря 2008
$('<div/>').text('This is fun & stuff').html(); // "This is fun &amp; stuff"

Источник: http://debuggable.com/posts/encode-html-entities-with-jquery:480f4dd6-13cc-4ce9-8071-4710cbdd56cb

60 голосов
/ 24 августа 2008

Если вы переходите на HTML, я думаю, есть только три, которые действительно необходимы:

html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");

В зависимости от вашего варианта использования, вам также может понадобиться сделать что-то вроде " до &quot;. Если бы список стал достаточно большим, я бы просто использовал массив:

var escaped = html;
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]
for(var item in findReplace)
    escaped = escaped.replace(findReplace[item][0], findReplace[item][1]);

encodeURIComponent() исключит его только для URL, а не для HTML.

36 голосов
/ 14 ноября 2012

Я написал крошечную маленькую функцию, которая делает это. Это только экранирование ", &, < и > (но обычно это все, что вам нужно в любом случае). Это немного более элегантно, чем ранее предложенные решения в том, что он использует только one .replace(), чтобы сделать все преобразования. ( РЕДАКТИРОВАТЬ 2: Снижение сложности кода, что делает функцию еще меньше и удобнее, если вам интересно узнать об исходном коде, см. Конец этого ответа.)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&<>]/g, function (a) {
        return { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' }[a];
    });
}

Это обычный Javascript, jQuery не используется.

Бегство / и ' тоже

Редактировать в ответ на комментарий mklement .

Вышеуказанная функция может быть легко расширена для включения любого символа. Чтобы указать больше символов для экранирования, просто вставьте их как в класс символов в регулярном выражении (т. Е. Внутри /[...]/g), так и в виде записи в объекте chr. ( РЕДАКТ. 2: Аналогичным образом сократили и эту функцию.)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&'\/<>]/g, function (a) {
        return {
            '"': '&quot;', '&': '&amp;', "'": '&#39;',
            '/': '&#47;',  '<': '&lt;',  '>': '&gt;'
        }[a];
    });
}

Обратите внимание на вышеприведенное использование &#39; для апострофа (вместо этого можно было использовать символическую сущность &apos; - она ​​определена в XML, но изначально не была включена в спецификацию HTML и поэтому могла поддерживаться не всеми браузерами См .: Статья в Википедии о кодировке символов HTML ). Я также вспоминаю, что где-то читал, что использование десятичных сущностей более широко поддерживается, чем использование шестнадцатеричных, но сейчас я не могу найти источник для этого. (И не может быть много браузеров, которые не поддерживают шестнадцатеричные сущности.)

Примечание: Добавление / и ' в список экранированных символов не так уж и полезно, так как они не имеют никакого особого значения в HTML и не нужны чтобы сбежать.

Оригинал escapeHtml Функция

EDIT 2: Исходная функция использовала переменную (chr) для хранения объекта, необходимого для обратного вызова .replace(). Эта переменная также нуждалась в дополнительной анонимной функции для ее расширения, что делало функцию (без необходимости) немного больше и сложнее.

var escapeHtml = (function () {
    'use strict';
    var chr = { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };
    return function (text) {
        return text.replace(/[\"&<>]/g, function (a) { return chr[a]; });
    };
}());

Я не проверял, какая из двух версий быстрее. Если у вас есть, не стесняйтесь добавлять информацию и ссылки о ней здесь.

35 голосов
/ 12 сентября 2013

Достаточно прост в использовании подчеркивание:

_.escape(string) 

Underscore - это служебная библиотека, которая предоставляет множество функций, которые не предоставляет нативный js. Также есть lodash , который является тем же API, что и подчеркивание, но был переписан для большей производительности.

31 голосов
/ 02 марта 2016

Я понимаю, как поздно я на этой вечеринке, но у меня есть очень простое решение, которое не требует jQuery.

escaped = new Option(unescaped).innerHTML;

Редактировать: это не экранирует кавычки. Единственный случай, когда необходимо экранировать кавычки, - это если содержимое будет вставлено внутри атрибута в строке HTML. Мне трудно представить себе случай, когда это было бы хорошим дизайном.

Редактировать 2: Если производительность имеет решающее значение, решение с самой высокой производительностью (примерно на 50%) по-прежнему представляет собой серию регулярных выражений. Современные браузеры обнаружат, что регулярные выражения не содержат операторов, только строку, и свернут все в одну операцию.

30 голосов
/ 31 мая 2012

Вот простая и понятная функция JavaScript. Это будет экранировать текст, такой как «несколько <многие» в «несколько & lt; многие». </p>

function escapeHtmlEntities (str) {
  if (typeof jQuery !== 'undefined') {
    // Create an empty div to use as a container,
    // then put the raw text in and get the HTML
    // equivalent out.
    return jQuery('<div/>').text(str).html();
  }

  // No jQuery, so use string replace.
  return str
    .replace(/&/g, '&amp;')
    .replace(/>/g, '&gt;')
    .replace(/</g, '&lt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&apos;');
}
26 голосов
/ 09 июля 2013

После последних тестов я могу порекомендовать самый быстрый и полностью кросс-браузерный совместимый собственный javaScript (DOM) решение:

function HTMLescape(html){
    return document.createElement('div')
        .appendChild(document.createTextNode(html))
        .parentNode
        .innerHTML
}

Если вы повторите это много раз, вы можете сделать это с подготовленными переменными:

//prepare variables
var DOMtext = document.createTextNode("test");
var DOMnative = document.createElement("span");
DOMnative.appendChild(DOMtext);

//main work for each case
function HTMLescape(html){
  DOMtext.nodeValue = html;
  return DOMnative.innerHTML
}

Посмотрите на мое последнее выступление сравнение ( стек вопросов ).

24 голосов
/ 20 августа 2012

Попробуйте Underscore.string lib, работает с jQuery.

_.str.escapeHTML('<div>Blah blah blah</div>')

выход:

'&lt;div&gt;Blah blah blah&lt;/div&gt;'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...