Ответы:
Примечание по безопасности: использование этого ответа (сохранено в его первоначальном виде ниже) может привести к уязвимости XSS в вашем приложении. Вы не должны использовать этот ответ. Прочитайте ответ Лукашаро, чтобы объяснить уязвимости в этом ответе, и вместо этого используйте подход из этого ответа или ответа Марка Эмери .
На самом деле, попробуйте
var decoded = $("<div/>").html(encodedStr).text();
$("<div/>").html('<img src="http://www.google.com/images/logos/ps_logo2.png" onload=alert(1337)>')
. В Firefox или Safari выдает предупреждение.
str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/g, "")
или что-то подобное.
Без каких-либо jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 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)">')
Тем не менее, эта атака невозможна против a, <textarea>
потому что нет элементов HTML, которым разрешено содержимое a <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)">'))
Предупреждение : Делать это, используя jQuery
.html()
и.val()
методы вместо использования,.innerHTML
а.value
также небезопасно * для некоторых версий jQuery, даже при использовании atextarea
. Это связано с тем, что более старые версии 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>
* Спасибо Эру Пенкману за обнаружение этой уязвимости.
decodedString = textArea.value;
textArea.remove();
return decodedString;
if ('remove' in Element.prototype) textArea.remove();
$("<div />").html(string).text()
выполнит любой javascript в предоставленной строке , что, я подозреваю, является причиной вашей проблемы. Принятый ответ должен быть обновлен до этого.
Как сказал Майк Сэмюэл, не используйте jQuery.html (). Text () для декодирования html-объектов, поскольку это небезопасно.
Вместо этого используйте средство визуализации шаблонов, такое как Mustache.js или decodeEntities из комментария @ VyvIT.
Underscore.jsБиблиотека утилит-пояса поставляется с escape
и unescape
методами, но они небезопасны для ввода пользователем:
unescape
в документы, кстати.
_.unescape("'")
в результате просто "& # 39;" вместо одиночной кавычки. Есть ли что-то, что я пропускаю или подчеркиваю, не скрываются ли
escape
и unescape
методы ... небезопасны для пользовательского ввода" . Что вы под этим подразумеваете? Для меня это звучит чепухой, но, может быть, я что-то упустил - вы можете уточнить?
_.unescape("<img src=fake onerror=alert('boo!')>")
(в Chrome / FF / IE). Но он не обнаружил никакого предупреждения. Пробовал в консоли, а также положить в мой файл JS тоже. Тот же результат.
Я думаю, что вы путаете текст и методы 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());" />
<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 - HTML декодировать и кодировать, который кодирует и декодирует HTML-строки.
Вопрос ограничен «с помощью jQuery», но это может помочь некоторым узнать, что код jQuery, приведенный в лучшем ответе здесь, выполняет следующее ниже ... это работает с или без jQuery:
function decodeEntities(input) {
var y = document.createElement('textarea');
y.innerHTML = input;
return y.value;
}
Вы можете использовать библиотеку he , доступную по адресу https://github.com/mathiasbynens/he
Пример:
console.log(he.decode("Jörg & Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
Я обратился к автору библиотеки с вопросом о том, была ли какая-либо причина использовать эту библиотеку в клиентском коде в пользу <textarea>
взлома, приведенного в других ответах здесь и в других местах. Он представил несколько возможных оправданий:
Если вы используете server.js на стороне сервера, использование библиотеки для кодирования / декодирования HTML дает вам единственное решение, которое работает как на стороне клиента, так и на стороне сервера.
Алгоритмы декодирования объектов в некоторых браузерах содержат ошибки или не поддерживают некоторые ссылки на именованные символы . Например, Internet Explorer будет
правильно декодировать и отображать неразрывные пробелы ( ), но сообщать о них как об обычных пробелах, а не неразрывных через innerText
свойство элемента DOM , нарушая <textarea>
взлом (хотя и незначительным образом). Кроме того, IE 8 и 9 просто не поддерживает какой - либо из новых именованных ссылок на символы , добавленные в HTML 5. Автор он также проводит проверку по имени справочной поддержки символов в http://mathias.html5.org/tests/html / именованные символьные ссылки / . В IE 8 сообщается более тысячи ошибок.
Если вы хотите быть изолированными от ошибок браузера, связанных с декодированием сущностей и / или иметь возможность обрабатывать полный диапазон именованных ссылок на символы, вы не можете избежать неприятностей <textarea>
; вам понадобится библиотека, как он .
Он просто чертовски хорош, чувствует себя так, как будто не так хакерски.
закодировать:
$("<textarea/>").html('<a>').html(); // return '<a>'
расшифровывает:
$("<textarea/>").html('<a>').val() // return '<a>'
использование
myString = myString.replace( /\&/g, '&' );
Проще всего сделать это на стороне сервера, потому что, очевидно, JavaScript не имеет встроенной библиотеки для обработки сущностей, и я не нашел ничего в верхней части результатов поиска для различных сред, расширяющих JavaScript.
Ищите «JavaScript HTML-сущности», и вы можете найти несколько библиотек именно для этой цели, но, вероятно, все они будут построены на основе вышеупомянутой логики - заменить сущность на сущность.
Мне просто нужно было использовать символ сущности HTML (⇓) в качестве значения кнопки HTML. HTML-код выглядит хорошо с самого начала в браузере:
<input type="button" value="Embed & Share ⇓" id="share_button" />
Теперь я добавил переключатель, который также должен отображать характер. Это мое решение
$("#share_button").toggle(
function(){
$("#share").slideDown();
$(this).attr("value", "Embed & Share " + $("<div>").html("⇑").text());
}
На дисплее снова отобразится ⇓. Я надеюсь, что это может кому-то помочь.
"Embed & Share \u21d1"
), или еще лучше, просто "Embed & Share ⇑"
если вы можете обслуживать свой сценарий в UTF-8 (или UTF-16, или в любой другой кодировке, поддерживающей символ ⇑). Использование элемента DOM для анализа HTML-сущности просто для того, чтобы запрограммировать произвольный символ Юникода в строку JavaScript, - это хитрый и творческий подход, который мог бы гордить Рубе Голдберга, но не является хорошей практикой; экранирование Юникода на языке специально для обработки этого варианта использования.
Вы должны сделать пользовательскую функцию для объектов HTML:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}
Предположим, у вас ниже строки.
Наши роскошные каюты теплые, уютные и удобный
var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text(); // Now,decode html entities in your variable i.e
ул и назначить обратно
тег.
Это оно.
Для пользователей ExtJS, если у вас уже есть закодированная строка, например, когда возвращаемое значение библиотечной функции является содержимым innerHTML, рассмотрите эту функцию ExtJS:
Ext.util.Format.htmlDecode(innerHtmlContent)
Расширить класс String:
String::decode = ->
$('<textarea />').html(this).text()
и использовать в качестве метода:
"<img src='myimage.jpg'>".decode()
Попробуй это :
var htmlEntities = "<script>alert('hello');</script>";
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 велико, поэтому функция будет разделять содержимое на множество индексов.
и чтобы получить все данные индексов, вы должны перейти к любому индексу, а затем получить доступ к индексу, называемому «целым текстом».
Я выбрал индекс 0, потому что он будет работать во всех случаях (маленькая строка или большая строка).
Вот еще одна проблема: Экранированная строка не выглядит читаемой при назначении входного значения
var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);
Пример: https://jsfiddle.net/kjpdwmqa/3/
escape
метод Underscore.js. Также нет объяснения, как ваш пример кода должен решить проблему OP.
Кроме того, есть библиотека для этого ..
здесь, 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('© Ande & Nonso® Company Limited 2018');
веселит.
Чтобы декодировать HTML-объекты с помощью jQuery, просто используйте эту функцию:
function html_entity_decode(txt){
var randomID = Math.floor((Math.random()*100000)+1);
$('body').append('<div id="random'+randomID+'"></div>');
$('#random'+randomID).html(txt);
var entity_decoded = $('#random'+randomID).html();
$('#random'+randomID).remove();
return entity_decoded;
}
Как пользоваться:
Javascript:
var txtEncoded = "á é í ó ú";
$('#some-id').val(html_entity_decode(txtEncoded));
HTML:
<input id="some-id" type="text" />
Самый простой способ - установить селектор класса на ваши элементы, а затем использовать следующий код:
$(function(){
$('.classSelector').each(function(a, b){
$(b).html($(b).text());
});
});
Больше ничего не нужно!
У меня была эта проблема, и я нашел это ясное решение, и оно отлично работает.