it-swarm.com.ru

HtmlSpecialChars эквивалент в Javascript?

Видимо, найти это сложнее, чем я думал. И это даже так просто ...

Есть ли функция, эквивалентная PHP htmlspecialchars, встроенная в Javascript? Я знаю, что это довольно легко реализовать самостоятельно, но использование встроенной функции, если она доступна, просто приятнее.

Для тех, кто не знаком с PHP, htmlspecialchars переводит такие вещи, как <htmltag/>, в &lt;htmltag/&gt;

Я знаю, что escape() и encodeURI() не работают таким образом.

143
Bart van Heukelom

Существует проблема с вашим кодом решения - он будет избегать только первое вхождение каждого специального символа. Например:

escapeHtml('Kip\'s <b>evil</b> "test" code\'s here');
Actual:   Kip&#039;s &lt;b&gt;evil</b> &quot;test" code's here
Expected: Kip&#039;s &lt;b&gt;evil&lt;/b&gt; &quot;test&quot; code&#039;s here

Вот код, который работает правильно:

function escapeHtml(text) {
  return text
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
}

Обновление

Следующий код даст результаты, идентичные приведенным выше, но он работает лучше, особенно на больших блоках текста (спасибо jbo5112 ).

function escapeHtml(text) {
  var map = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };

  return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}
285
Kip

Это кодировка HTML. Для этого нет встроенной функции javascript, но вы можете подключиться к Google и получить некоторые из них.

Например. http://sanzon.wordpress.com/2008/05/01/neat-little-html-encoding-trick-in-javascript/

Правка:
Вот что я проверял:

var div = document.createElement('div');
  var text = document.createTextNode('<htmltag/>');
  div.appendChild(text);
  console.log(div.innerHTML);

Вывод: &lt;htmltag/&gt;

29
o.k.w

Стоит прочитать: http://bigdingus.com/2007/12/29/html-escaping-in-javascript/

escapeHTML: (function() {
 var MAP = {
   '&': '&amp;',
   '<': '&lt;',
   '>': '&gt;',
   '"': '&#34;',
   "'": '&#39;'
 };
  var repl = function(c) { return MAP[c]; };
  return function(s) {
    return s.replace(/[&<>'"]/g, repl);
  };
})()

Примечание: запускать только один раз. И не запускайте его на уже закодированных строках, например &amp; становится &amp;amp;

25
Chris Jacob

С jQuery это может быть так:

var escapedValue = $('<div/>').text(value).html();

Из смежного вопроса Экранирование строк HTML с помощью jQuery

Как упомянуто в комментарии, двойные кавычки и одинарные кавычки оставлены как есть для этой реализации. Это означает, что это решение не следует использовать, если вам нужно сделать атрибут элемента в виде необработанной HTML-строки.

19
Alexander Yanovets

Вот функция для выхода из HTML:

function escapeHtml(str)
{
    var map =
    {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
    };
    return str.replace(/[&<>"']/g, function(m) {return map[m];});
}

И расшифровать:

function decodeHtml(str)
{
    var map =
    {
        '&amp;': '&',
        '&lt;': '<',
        '&gt;': '>',
        '&quot;': '"',
        '&#039;': "'"
    };
    return str.replace(/&amp;|&lt;|&gt;|&quot;|&#039;/g, function(m) {return map[m];});
}
15
Dan Bray

Underscore.js предоставляет функцию для этого:

_.escape(string)

Исключает строку для вставки в HTML, заменяя символы &, <,>, "и".

http://underscorejs.org/#escape

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

6
mer10z_tech

Еще один способ сделать это состоит в том, чтобы полностью отказаться от отображения всех символов и вместо этого преобразовать все нежелательные символы в соответствующие им числовые ссылки на символы, например:

function escapeHtml(raw) {
    return raw.replace(/[&<>"']/g, function onReplace(match) {
        return '&#' + match.charCodeAt(0) + ';';
    });
}

Обратите внимание, что указанный RegEx обрабатывает только определенные символы, которые OP хотел экранировать, но, в зависимости от контекста, в котором будет использоваться экранированный HTML, этих символов может быть недостаточно. Статья Райана Гроува В HTML есть нечто большее, чем &, <,> и " - хорошее прочтение по этой теме. И в зависимости от вашего контекста может потребоваться следующий RegEx, чтобы избежать внедрения XSS:

var regex = /[&<>"'` [email protected]$%()=+{}[\]]/g
5
Fredric
String.prototype.escapeHTML = function() {
        return this.replace(/&/g, "&amp;")
                   .replace(/</g, "&lt;")
                   .replace(/>/g, "&gt;")
                   .replace(/"/g, "&quot;")
                   .replace(/'/g, "&#039;");
    }

образец : 

var toto = "test<br>";
alert(toto.escapeHTML());
3
patrick

Скорее всего, вам не нужна такая функция. Поскольку ваш код уже находится в браузере *, вы можете получить доступ к DOM напрямую, а не генерировать и кодировать HTML, который должен быть декодирован в обратном направлении браузером, чтобы фактически использоваться.

Используйте свойство innerText для безопасного и простого вставления простого текста в DOM, чем при использовании любой из представленных escape-функций. Даже быстрее чем назначение статической предварительно кодированной строки для innerHTML.

Используйте classList для редактирования классов, dataset для установки атрибутов data- и setAttribute для других.

Все это поможет вам убежать. Точнее, экранирование не требуется, и кодирование не будет выполняться под **, поскольку вы работаете с HTML, текстовым представлением DOM.

// use existing element
var author = 'John "Superman" Doe <[email protected]>';
var el = document.getElementById('first');
el.dataset.author = author;
el.textContent = 'Author: '+author;

// or create a new element
var a = document.createElement('a');
a.classList.add('important');
a.href = '/search?q=term+"exact"&n=50';
a.textContent = 'Search for "exact" term';
document.body.appendChild(a);

// actual HTML code
console.log(el.outerHTML);
console.log(a.outerHTML);
.important { color: red; }
<div id="first"></div>

* Этот ответ не предназначен для пользователей JavaScript на стороне сервера (Node.js, и т.д. )

** Если вы явно не конвертируете его в фактический HTML впоследствии. Например. путем доступа к innerHTML - это то, что происходит, когда вы запускаете $('<div/>').text(value).html();, предложенную в других ответах. Поэтому, если ваша конечная цель - вставить некоторые данные в документ, сделав это таким образом, вы сделаете эту работу дважды. Также вы можете видеть, что в полученном HTML не все закодировано, только тот минимум, который необходим для того, чтобы он был действительным. Это делается в зависимости от контекста, поэтому этот метод jQuery не кодирует кавычки и, следовательно, не должен использоваться в качестве escape-кода общего назначения. Экранирование кавычек необходимо, когда вы создаете HTML как строку с ненадежными или содержащими цитаты данными вместо значения атрибута. Если вы используете DOM API, вам вовсе не нужно заботиться о том, чтобы избежать этого.

3
user

Для пользователей Node.JS (или пользователей, использующих Jade Runtime в браузере), вы можете использовать функцию escape Jade.

require('jade').runtime.escape(...);

Нет смысла писать это самостоятельно, если кто-то другой поддерживает это. :)

2
BMiner
function htmlEscape(str){
    return str.replace(/[&<>'"]/g,x=>'&#'+x.charCodeAt(0)+';')
}

В этом решении используется числовой код символов, например, < заменяется на &#60;.

Хотя его производительность немного хуже, чем у решения, использующего карту , у него есть свои преимущества:

  • Не зависит от библиотеки или DOM
  • Довольно легко запомнить (вам не нужно запоминать 5 экранирующих символов HTML)
  • Маленький код
  • Достаточно быстро (это все же быстрее, чем 5 цепочек замены)
0
user202729

Я немного уточняю ответ О.К.

Для этого вы можете использовать функции DOM браузера. 

var utils = {
    dummy: document.createElement('div'),
    escapeHTML: function(s) {
        this.dummy.textContent = s
        return this.dummy.innerHTML
    }
}

utils.escapeHTML('<escapeThis>&')

Это возвращает &lt;escapeThis&gt;&amp;

Он использует стандартную функцию createElement для создания невидимого элемента, затем использует функцию textContent для установки любой строки в качестве ее содержимого и затем innerHTML для получения содержимого в его представлении HTML.

0
Jonas Eberle

Надеюсь, что это выиграет гонку из-за ее производительности и, что важнее всего, не цепочки логики с использованием .replace ('&', '&'). Replace ('<', '<') ...

var mapObj = {
   '&':"&amp;",
   '<':"&lt;",
   '>':"&gt;",
   '"':"&quot;",
   '\'':"&#039;"
};
var re = new RegExp(Object.keys(mapObj).join("|"),"gi");

function escapeHtml(str) 
{   
    return str.replace(re, function(matched)
    {
        return mapObj[matched.toLowerCase()];
    });
}

console.log('<script type="text/javascript">alert('Hello World');</script>');
console.log(escapeHtml('<script type="text/javascript">alert('Hello World');</script>'));
0
Abdul Jabbar Dumrai

Перевернутый один:

function decodeHtml(text) {
    return text
        .replace(/&amp;/g, '&')
        .replace(/&lt;/ , '<')
        .replace(/&gt;/, '>')
        .replace(/&quot;/g,'"')
        .replace(/&#039;/g,"'");
}
0
Gleb Dolzikov
function htmlspecialchars(str) {
 if (typeof(str) == "string") {
  str = str.replace(/&/g, "&amp;"); /* must do &amp; first */
  str = str.replace(/"/g, "&quot;");
  str = str.replace(/'/g, "&#039;");
  str = str.replace(/</g, "&lt;");
  str = str.replace(/>/g, "&gt;");
  }
 return str;
 }
0
user1477929