Каков правильный способ декодирования строки, в которой есть специальные объекты HTML?
Скажем, я получаю JSON обратно из запроса службы, который выглядит так:
{
"message": "We're unable to complete your request at this time."
}
Я не уверен, почему этот апострап закодирован таким образом ('
); все, что я знаю, это то, что я хочу его декодировать.
Здесь один подход с использованием jQuery, который появился в моей голове:
function decodeHtml(html) {
return $('<div>').html(html).text();
}
Это кажется (очень) взломанным. Какой лучший способ? Есть ли "правильный" способ?
Ответы
Ответ 1
Это мой любимый способ декодирования символов HTML. Преимущество использования этого кода в том, что теги также сохраняются.
function decodeHtml(html) {
var txt = document.createElement("textarea");
txt.innerHTML = html;
return txt.value;
}
Пример: http://jsfiddle.net/k65s3/
Input:
Entity: Bad attempt at XSS:<script>alert('new\nline?')</script><br>
Вывод:
Entity: Bad attempt at XSS:<script>alert('new\nline?')</script><br>
Ответ 2
Не используйте DOM для этого. Использование DOM для декодирования объектов HTML (как предлагается в принятом в настоящее время ответе) приводит к различия в результатах кросс-браузера.
Для надежного и детерминированного решения, которое декодирует ссылки на символы в соответствии с алгоритмом в стандарте HTML, используйте его библиотеку. Из README:
he (для "HTML-сущностей" ) - это надежный кодировщик/декодер объектов HTML, написанный на JavaScript. Он поддерживает все стандартизированные именованные символы в соответствии с HTML, обрабатывает неоднозначные амперсанды и другие случаи ребер точно так же, как браузер, имеет обширный набор тестов и, вопреки многим другим решениям JavaScript, он обрабатывает астральный Unicode символы просто прекрасные. Доступна онлайн-демонстрация.
Вот как вы его используете:
he.decode("We're unable to complete your request at this time.");
→ "We're unable to complete your request at this time."
Отказ от ответственности: я автор библиотеки.
См. этот ответ для получения дополнительной информации.
Ответ 3
Если вы не хотите использовать html/dom, вы можете использовать регулярное выражение. Я не тестировал это; но что-то вроде:
function parseHtmlEntities(str) {
return str.replace(/&#([0-9]{1,3});/gi, function(match, numStr) {
var num = parseInt(numStr, 10); // read num as normal number
return String.fromCharCode(num);
});
}
[изменить]
Примечание: это будет работать только для числовых html-сущностей, а не для таких вещей, как & oring;.
[Изменить 2]
Исправлена функция (некоторые опечатки), здесь: http://jsfiddle.net/Be2Bd/1/
Ответ 4
jQuery будет кодироваться и декодироваться для вас.
function htmlDecode(value) {
return $("<textarea/>").html(value).text();
}
function htmlEncode(value) {
return $('<textarea/>').text(value).html();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#encoded")
.text(htmlEncode("<img src onerror='alert(0)'>"));
$("#decoded")
.text(htmlDecode("<img src onerror='alert(0)'>"));
});
</script>
<div id="encoded"></div>
<div id="decoded"></div>
Ответ 5
Там JS-функция для работы с объектами #xxxx:
функция в GitHub
// encode(decode) html text into html entity
var decodeHtmlEntity = function(str) {
return str.replace(/&#(\d+);/g, function(match, dec) {
return String.fromCharCode(dec);
});
};
var encodeHtmlEntity = function(str) {
var buf = [];
for (var i=str.length-1;i>=0;i--) {
buf.unshift(['&#', str[i].charCodeAt(), ';'].join(''));
}
return buf.join('');
};
var entity = '高级程序设计';
var str = '高级程序设计';
console.log(decodeHtmlEntity(entity) === str);
console.log(encodeHtmlEntity(str) === entity);
// output:
// true
// true
Ответ 6
_.unescape
выполняет то, что вы ищете
http://underscorejs.org/#unescape
Ответ 7
Это хороший ответ. Вы можете использовать это с помощью angular следующим образом:
moduleDefinitions.filter('sanitize', ['$sce', function($sce) {
return function(htmlCode) {
var txt = document.createElement("textarea");
txt.innerHTML = htmlCode;
return $sce.trustAsHtml(txt.value);
}
}]);