it-swarm.com.ru

Как декодировать HTML-сущности с помощью jQuery?

Как я могу использовать jQuery для декодирования HTML-объектов в строке?

314
EddyR

Примечание по безопасности: использование этого ответа (сохранено в его первоначальном виде ниже) может привести к уязвимости XSS в вашем приложении. Вы не должны использовать этот ответ. Прочтите ответ Лукашаро для объяснения уязвимостей в этом ответе, и используйте вместо этого подход либо из этого ответа, либо Марк Амери .

На самом деле, попробуйте 

var decoded = $("<div/>").html(encodedStr).text();
426
tom

Без каких-либо jQuery:

function decodeEntities(encodedString) {
  var textArea = document.createElement('textarea');
  textArea.innerHTML = encodedString;
  return textArea.value;
}

console.log(decodeEntities('1 &amp; 2')); // '1 & 2'

Это работает аналогично принятый ответ , но безопасно для использования с ненадежным пользовательским вводом.


Проблемы безопасности в аналогичных подходах

Как отметил Майк Самуэль , выполнение этого с помощью <div> вместо <textarea> с ненадежным пользовательским вводом является уязвимостью XSS, даже если <div> никогда не добавляется в DOM:

function decodeEntities(encodedString) {
  var div = document.createElement('div');
  div.innerHTML = encodedString;
  return div.textContent;
}

// Shows an alert
decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">')

Однако эта атака невозможна в отношении <textarea>, поскольку нет элементов HTML, которым разрешено содержимое <textarea> . Следовательно, любые HTML-теги, все еще присутствующие в «кодированной» строке, будут автоматически кодироваться сущностью браузером.

function decodeEntities(encodedString) {
    var textArea = document.createElement('textarea');
    textArea.innerHTML = encodedString;
    return textArea.value;
}

// Safe, and returns the correct answer
console.log(decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">'))

Warning: Делать это с помощью методов jQuery .html() и .val() вместо использования .innerHTML и .value также небезопасно * для некоторых версий jQuery, даже при использовании textarea. Это связано с тем, что более ранние версии jQuery будут преднамеренно и явно оценивать скрипты , содержащиеся в строке, передаваемой .html(). Следовательно, код, подобный этому, показывает предупреждение в jQuery 1.8:

//<!-- CDATA
// Shows alert
$("<textarea>")
.html("<script>alert(1337);</script>")
.text();

//-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>

* Спасибо Эру Пенкман за обнаружение этой уязвимости.

187
lucascaro

Как сказал Майк Сэмюэл, не используйте jQuery.html (). Text () для декодирования html-объектов, поскольку это небезопасно.

Вместо этого используйте средство визуализации шаблонов, например Mustache.js или decodeEntities из комментария @ VyvIT.

Underscore.js библиотека утилит-пояса поставляется с методами escape и unescape, но они небезопасны для ввода пользователем:

_.escape (строка)

_.unescape (строка)

77
Alan Hamlett

Я думаю, что вы путаете текст и методы HTML. Посмотрите на этот пример, если вы используете внутренний HTML-код элемента в качестве текста, вы получите декодированные HTML-теги (вторая кнопка). Но если вы используете их как HTML, вы получите представление в формате HTML (первая кнопка).

<div id="myDiv">
    here is a <b>HTML</b> content.
</div>
<br />
<input value="Write as HTML" type="button" onclick="javascript:$('#resultDiv').html($('#myDiv').html());" />
&nbsp;&nbsp;
<input value="Write as Text" type="button" onclick="javascript:$('#resultDiv').text($('#myDiv').html());" />
<br /><br />
<div id="resultDiv">
    Results here !
</div>

Первая кнопка пишет: вот содержание HTML

Вторая кнопка пишет: здесь находится контент <B> HTML </ B>. 

Кстати, вы можете увидеть плагин, который я нашел в jQuery plugin - HTML decode and encode, который кодирует и декодирует HTML-строки.

28
Canavar

Вопрос ограничен «с помощью jQuery», но это может помочь некоторым узнать, что код jQuery, приведенный в лучшем ответе здесь, выполняет следующее ниже ... это работает с или без jQuery:

function decodeEntities(input) {
  var y = document.createElement('textarea');
  y.innerHTML = input;
  return y.value;
}
26
Rondo

закодировать:

$("<textarea/>").html('<a>').html();      // return '&lt;a&gt'

расшифровывает:

$("<textarea/>").html('&lt;a&gt').val()   // return '<a>'
16
user4064396

Вы можете использовать библиотеку he, доступную по адресу https://github.com/mathiasbynens/he

Пример:

console.log(he.decode("J&#246;rg &amp J&#xFC;rgen rocked to &amp; fro "));
// Logs "Jörg & Jürgen rocked to & fro"

Я бросил вызов автору библиотеки по вопросу о том, была ли какая-либо причина использовать эту библиотеку в клиентском коде в пользу взлома <textarea>, предоставленного в других ответах здесь и в других местах. Он представил несколько возможных оправданий:

  • Если вы используете серверный файл node.js, использование библиотеки для кодирования/декодирования HTML дает вам единственное решение, которое работает как на стороне клиента, так и на стороне сервера.

  • Алгоритмы декодирования сущностей некоторых браузеров содержат ошибки или не поддерживают некоторые именованные ссылки на символы . Например, Internet Explorer будет правильно декодировать и отображать неразрывные пробелы (&nbsp;), но сообщать о них как об обычных пробелах, а не неразрывных через свойство innerText элемента DOM, ломая хак <textarea> (хотя и незначительным образом). Кроме того, IE 8 и 9 просто не поддерживают любые новые ссылки на именованные символы, добавленные в HTML 5. Автор he также проводит тест поддержки ссылок на именованные символы на http://mathias.html5.org/tests/html/named-character-references/ . В IE 8 сообщается о более чем тысяче ошибок.

    Если вы хотите быть изолированным от ошибок браузера, связанных с декодированием сущностей и/или иметь возможность обрабатывать полный диапазон именованных ссылок на символы, вы не можете избежать хака <textarea>; вам понадобится библиотека вроде he.

  • Он просто чертовски хорош, чувствует себя так, как будто не так хакерски.

15
Mark Amery

Использование

myString = myString.replace( /\&amp;/g, '&' );

Проще всего сделать это на стороне сервера, потому что, очевидно, JavaScript не имеет встроенной библиотеки для обработки сущностей, и я не нашел ничего в верхней части результатов поиска для различных сред, расширяющих JavaScript. 

Выполните поиск «JavaScript HTML-сущностей», и вы можете найти несколько библиотек именно для этой цели, но, вероятно, все они будут построены на основе вышеуказанной логики - заменить сущность на сущность.

4
Dara

Вы должны сделать пользовательскую функцию для объектов HTML:

function htmlEntities(str) {
return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g,'&gt;').replace(/"/g, '&quot;');
}
1
Ali

Мне просто нужно было использовать символ сущности HTML (⇓) в качестве значения кнопки HTML. HTML-код выглядит хорошо с самого начала в браузере:

<input type="button" value="Embed & Share  &dArr;" id="share_button" />

Теперь я добавил переключатель, который также должен отображать характер. Это мое решение

$("#share_button").toggle(
    function(){
        $("#share").slideDown();
        $(this).attr("value", "Embed & Share " + $("<div>").html("&uArr;").text());
    }

На дисплее снова отобразится ⇓. Я надеюсь, что это может кому-то помочь.

0
philipp

Кроме того, есть также библиотека для этого ..

здесь, https://cdnjs.com/libraries/he

npm install he                 //using node.js

<script src="js/he.js"></script>  //or from your javascript directory

Использование заключается в следующем ... 

//to encode text 
he.encode('© Ande & Nonso® Company LImited 2018');  

//to decode the 
he.decode('&copy; Ande &amp; Nonso&reg; Company Limited 2018');

веселит.

0
Andaeiii

Вот еще одна проблема: Экранированная строка не выглядит читаемой при назначении входного значения

var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);

Пример: https://jsfiddle.net/kjpdwmqa/3/

0
Lauris Kuznecovs

Расширить класс String:

String::decode = ->
  $('<textarea />').html(this).text()

и использовать в качестве метода:

"&lt;img src='myimage.jpg'&gt;".decode()
0
Sergio Belevskij

Попробуй это :

var htmlEntities = "&lt;script&gt;alert('hello');&lt;/script&gt;";
var htmlDecode =$.parseHTML(htmlEntities)[0]['wholeText'];
console.log(htmlDecode);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

parseHTML - это функция в библиотеке Jquery, которая возвращает массив, содержащий некоторые подробности о данной строке.

в некоторых случаях значение String велико, поэтому функция будет разделять содержимое на множество индексов.

и чтобы получить все данные индексов, вы должны перейти к любому индексу, а затем получить доступ к индексу, называемому «wholeText».

Я выбрал индекс 0, потому что он будет работать во всех случаях (маленькая строка или большая строка).

0
Fawaz Al Romy

Для пользователей ExtJS, если у вас уже есть закодированная строка, например, когда возвращаемое значение библиотечной функции является содержимым innerHTML, рассмотрите эту функцию ExtJS:

Ext.util.Format.htmlDecode(innerHtmlContent)
0
Ilan

Предположим, у вас ниже строки.

Наши роскошные каюты теплые, уютные и удобный

var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text();  // Now,decode html entities in your variable i.e 

ул и назначить обратно 

тег.

вот и все.

0
Anirudh Sood