我如何编码和解码HTML实体使用JavaScript或JQuery?

var varTitle = "Chris' corner";

我希望它是:

var varTitle = "Chris' corner";

当前回答

就像Robert K说的,不要使用jQuery.html().text()来解码html实体,因为这是不安全的,因为用户输入永远不能访问DOM。阅读关于XSS的文章,了解为什么这是不安全的。

相反,尝试使用带有escape和unescape方法的Underscore.js实用带库:

_.escape(string)

转义插入HTML的字符串,替换&,<,>,",',和'字符。

_.escape('Curly, Larry & Moe');
=> "Curly, Larry &amp; Moe"

_.unescape(string)

escape的反义词,代替&, &lt;, &gt;, &quot;, &#96;和& # x27;和他们没有逃脱的同伴。

_.unescape('Curly, Larry &amp; Moe');
=> "Curly, Larry & Moe"

要支持解码更多字符,只需复制下划线unescape方法并向映射添加更多字符。

其他回答

我知道我有点晚了,但我认为我可以提供以下片段作为我如何使用jQuery解码HTML实体的示例:

var varTitleE = "Chris&apos; corner";
var varTitleD = $("<div/>").html(varTitleE).text();

console.log(varTitleE + " vs. " + varTitleD);​​​​​​​​​​​

不要忘记启动检查器/firebug以查看控制台结果——或者简单地将console.log(…)替换为/alert(…)

也就是说,以下是我的控制台通过谷歌Chrome检查器读取的内容:

Chris&apos; corner vs. Chris' corner

受Robert K的解决方案的启发,剥离html标签,防止执行脚本和事件处理程序,如:<img src=fake onerror="prompt(1)" > 在最新的Chrome, FF, IE上测试(应该可以在IE9上工作,但还没有测试)。

var decodeEntities = (function () {
        //create a new html document (doesn't execute script tags in child elements)
        var doc = document.implementation.createHTMLDocument("");
        var element = doc.createElement('div');

        function getText(str) {
            element.innerHTML = str;
            str = element.textContent;
            element.textContent = '';
            return str;
        }

        function decodeHTMLEntities(str) {
            if (str && typeof str === 'string') {
                var x = getText(str);
                while (str !== x) {
                    str = x;
                    x = getText(x);
                }
                return x;
            }
        }
        return decodeHTMLEntities;
    })();

简单地调用:

decodeEntities('<img src=fake onerror="prompt(1)">');
decodeEntities("<script>alert('aaa!')</script>");

@William Lahti的回答有一个更实用的方法:

var entities = {
  'amp': '&',
  'apos': '\'',
  '#x27': '\'',
  '#x2F': '/',
  '#39': '\'',
  '#47': '/',
  'lt': '<',
  'gt': '>',
  'nbsp': ' ',
  'quot': '"'
}

function decodeHTMLEntities (text) {
  return text.replace(/&([^;]+);/gm, function (match, entity) {
    return entities[entity] || match
  })
}

要做到这一点,在纯javascript没有jquery或预定义一切,你可以循环编码的html字符串通过元素innerHTML和innerText(/textContent)属性的每解码步骤,这是必需的:

<html>
  <head>
    <title>For every decode step, cycle through innerHTML and innerText </title>
    <script>
function decode(str) {
  var d = document.createElement("div");
  d.innerHTML = str; 
  return typeof d.innerText !== 'undefined' ? d.innerText : d.textContent;
}
    </script>
  </head>
  <body>
    <script>
var encodedString = "&lt;p&gt;name&lt;/p&gt;&lt;p&gt;&lt;span style=\"font-size:xx-small;\"&gt;ajde&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;da&lt;/em&gt;&lt;/p&gt;";
    </script>
    <input type=button onclick="document.body.innerHTML=decode(encodedString)"/>
  </body>
</html>

这里有一个不需要创建div的快速方法,并解码“最常见的”HTML转义字符:

function decodeHTMLEntities(text) {
    var entities = [
        ['amp', '&'],
        ['apos', '\''],
        ['#x27', '\''],
        ['#x2F', '/'],
        ['#39', '\''],
        ['#47', '/'],
        ['lt', '<'],
        ['gt', '>'],
        ['nbsp', ' '],
        ['quot', '"']
    ];

    for (var i = 0, max = entities.length; i < max; ++i) 
        text = text.replace(new RegExp('&'+entities[i][0]+';', 'g'), entities[i][1]);

    return text;
}