Відповіді:
Примітка безпеки: використання цієї відповіді (збережена в початковій формі нижче) може ввести в вашу програму вразливість 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)">')
Однак ця атака не можлива, <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)">'))
Попередження : Виконайте це, використовуючи jQuery's
.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
Зараз вони включені в документи, btw.
_.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;
}
Ви можете використовувати він бібліотеку, доступну з 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>
хаку, передбаченого в інших відповідях тут і в інших місцях. Він надав кілька можливих обгрунтування:
Якщо ви використовуєте сервер node.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.
Шукайте "HTML-об'єкти JavaScript", і ви можете знайти декілька бібліотек саме для цієї мети, але вони, ймовірно, будуть побудовані навколо вищезгаданої логіки - заміни, сутності за сутністю.
Я просто повинен був мати характер 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 просто для введення довільного символу Unicode в рядок JavaScript - хитрий та креативний підхід, який зробить Рубе Голдберга гордим, але це не є хорошою практикою; Юнікодні виводи є мовою, спеціально для обробки цього випадку використання.
Ви повинні створити власну функцію для html-об'єктів:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}
Припустимо, у вас нижче String.
Наші кабіни Deluxe теплі, затишні та підсилювачі; зручні
var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text(); // Now,decode html entities in your variable i.e
str та призначити назад до
тег.
Це воно.
Для користувачів ExtJS, якщо у вас вже є кодована рядок, наприклад, коли повернене значення функції бібліотеки є внутрішнім вмістом HTMLML, врахуйте цю функцію 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, і вона поверне масив, який включає деякі деталі щодо даної рядка ..
в деяких випадках рядок є великим, тому функція розділить вміст на багато індексів.
і щоб отримати всі дані індексів, вам слід перейти до будь-якого індексу, а потім отримати доступ до індексу під назвою "fullText".
Я вибрав індекс 0, тому що він буде працювати у всіх випадках (маленький рядок або великий рядок).
Тут є ще одна проблема: уникнутий рядок не виглядає читабельним при призначенні вхідного значення
var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);
Exapmle: https://jsfiddle.net/kjpdwmqa/3/
escape
метод Underscore.js. Також немає пояснень, як ваш зразок коду повинен вирішити проблему ОП.
Крім того, є також бібліотека для нього.
тут, 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());
});
});
Більше нічого не потрібно!
У мене була ця проблема, і я знайшов це чітке рішення, і воно прекрасно працює.