说我从看起来像这样的服务请求中获取了一些JSON:

{
    "message": "We're unable to complete your request at this time."
}


我不确定为什么撇号是这样编码的(' );我所知道的是我想对其进行解码。

这是一种使用jQuery的方法突然出现在我的脑海:

function decodeHtml(html) {
    return $('<div>').html(html).text();
}


但是)有什么更好的方法?有“正确”的方法吗?

评论

可能的重复项:stackoverflow.com/questions/5796718/html-entity-decode

#1 楼

这是我最喜欢的解码HTML字符的方式。使用此代码的优点是还可以保留标签。

function decodeHtml(html) {
    var txt = document.createElement("textarea");
    txt.innerHTML = html;
    return txt.value;
}


示例:http://jsfiddle.net/k65s3/

输入:

Entity:&nbsp;Bad attempt at XSS:<script>alert('new\nline?')</script><br>


输出:

Entity: Bad attempt at XSS:<script>alert('new\nline?')</script><br>


评论


嗯,似乎基本上与我采用的方法相同,但是没有jQuery依赖关系(很好)。但是,它看起来还是很黑吗?还是我应该完全满意?

–丹涛
2011-09-12 22:33

哦,等等,我明白了:您正在专门使用textarea,以便保留标签(如您所说),但是HTML实体仍然会被解码。相当聪明...

–丹涛
2011-09-12 22:34

可以接受这是解码HTML的最佳方法。与原始解决方案不同,不会传递任何标签(解析(因此隐藏)标签)。

– Rob W
2011-09-12 22:34

好招!我已经使用了一段时间的非文本区域版本,到目前为止,这是更好的选择。

–Domenic
2011年9月12日在22:49

@Leonardo永远不会附加到文档中。

– Rob W
15年9月29日在12:56

#2 楼

不要使用DOM来做到这一点。使用DOM解码HTML实体(如当前接受的答案所建议)会导致跨浏览器结果的差异。

对于健壮且确定性的解决方案,该解决方案可以根据HTML中的算法对字符引用进行解码标准,使用he库。从其自述文件:


他(对于“ HTML实体”)是用JavaScript编写的健壮的HTML实体编码器/解码器。它按照HTML支持所有标准化的命名字符引用,像浏览器一样处理歧义的“&”号和其他边缘情况,具有广泛的测试套件,并且-与许多其他JavaScript解决方案相反-他可以很好地处理星体Unicode符号。在线演示可用。


这里是您的用法:

he.decode("We&#39;re unable to complete your request at this time.");
→ "We're unable to complete your request at this time."


免责声明:我是作者he库的内容。

有关更多信息,请参见此Stack Overflow答案。

评论


我当时在NodeJS中,所以对我来说这是唯一可用的解决方案。

–奥古斯丁·里丁格(Augustin Riedinger)
17年6月23日在13:14

我正在编写一个浏览器插件,该插件将页面抓了一些东西,因此基于dom的解决方案不是问题。这取决于上下文。

–雷·福斯(Ray Foss)
17年7月28日在16:28



“导致跨浏览器结果差异的重要性”。是吗在哪种浏览器中,结果可能会大不相同?您能给我确切的例子吗(在您看来,这是最重要的)?我不想使用过多的第三方库,所以我想先了解一下。

– Taufik Nur Ra​​hmanda
17年12月29日在3:29

@TaufikNurRahmanda指向该问题答案的链接。

–玛蒂亚斯·拜恩斯(Mathias Bynens)
18年1月16日在10:14

这个应该是正确的答案。比lodash和下划线更好。

–王ony
4月27日4:55

#3 楼

如果您不想使用html / dom,则可以使用regex。我还没有测试过但是类似以下内容:

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 ;. >

评论


What about & and other named entities? These are still not parsed in this implementation.

– Rob W
Sep 12 '11 at 22:36

我已经评论了它们将不会被解析的事实。要解析它们,您需要某种哈希表(查找)。但是,如果此代码是自动生成的(可以说),则它总是会返回数字值。我只提供了一种纯js的方式(没有DOM即可工作),并不是说它解决了一般性问题,而是解决了特定问题。

– Alxandr
2011年9月12日在22:45

Not working with > <

– Arthur Araújo
Dec 23 '16 at 13:25

I've just used this JSFiddle with one slight change, {1,3} to {1,4} which also allows for more characters, such as en dashes (–). For future reference, anyone else have this for other tags, such as > ?

– davewoodhall
Oct 15 '17 at 23:40

在正则表达式匹配/(pattern)/ gi中,不需要我后缀忽略大小写,因为这只会匹配数字。连同davewoodhall的评论,我正在使用/&#([0-9] {1,4}); / g

– Stephen P
18年2月28日在1:07

#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("&lt;img src onerror='alert(0)'&gt;"));
});
</script>

<span>htmlEncode() result:</span><br/>
<div id="encoded"></div>
<br/>
<span>htmlDecode() result:</span><br/>
<div id="decoded"></div> 




评论


作为参考,任何“元素”都可以在这里使用。在这里进行工作的文本区域没有什么神奇之处。但这就是说,如果您已经在使用jQuery,那么我总是会采用这种方法来获得出色的结果。

– Pim
16-3-21在20:54



我不同意。 Textarea提供了其他元素(例如divs)不会提供的安全性。如果您使用div而不是textarea,则输入中任何未编码的javascript都将在浏览器中呈现。通过将输入视为文本...而不是html,textarea可以解决此问题。我没有尝试过其他元素来了解它们的行为。

–詹森·威廉姆斯(Jason Williams)
16 Mar 23 '16 at 12:53

只是为了进一步澄清:如果您确实要在转换后将html呈现在浏览器中,请将其包装在不是文本输入的元素中。

–斯巴达克斯
17年7月26日在15:33

#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 = '&#39640;&#32423;&#31243;&#24207;&#35774;&#35745;';
var str = '高级程序设计';
console.log(decodeHtmlEntity(entity) === str);
console.log(encodeHtmlEntity(str) === entity);
// output:
// true
// true


评论


谢谢。此功能在#gatsbyjs应用程序中运行良好,该应用程序无法在静态HTML构建期间定义文档。

–大卫·加斯金(David Gaskin)
19年3月13日在7:34

这是应该做的!

–银
3月9日5:42

#6 楼

_.unescape可以满足您的需求

https://lodash.com/docs/#unescape

评论


it just replaces a few encoded characters - if you've got e.g. a   it stays the way it is.

– xtools
Jan 16 '18 at 10:41

e' is not in the list? This only replaces &, <, >, ", ` and '

– Jquestions
Dec 14 '18 at 11:25

更新了指向lodash.unescape的链接,该链接可处理&#39

–tldr
18/12/15在16:22

#7 楼

这是一个很好的答案。您可以将其与如下所示的角度一起使用:

 moduleDefinitions.filter('sanitize', ['$sce', function($sce) {
    return function(htmlCode) {
        var txt = document.createElement("textarea");
        txt.innerHTML = htmlCode;
        return $sce.trustAsHtml(txt.value);
    }
}]);


评论


尽管此代码可以回答问题,但提供有关如何和/或为什么解决问题的其他上下文将提高​​答案的长期价值。

– Nic3500
18年8月29日在16:59