HTML 实体解码

IT技术 javascript jquery html
2021-01-24 03:30:50

如何使用 JavaScript 或 JQuery 对 HTML 实体进行编码和解码?

var varTitle = "Chris' corner";

我希望它是:

var varTitle = "Chris' corner";
6个回答

我建议不要使用被接受为答案的 jQuery 代码。虽然它不会将要解码的字符串插入到页面中,但它确实会导致诸如脚本和 HTML 元素之类的内容被创建。这是比我们需要的更多的代码。相反,我建议使用更安全、更优化​​的函数。

var decodeEntities = (function() {
  // this prevents any overhead from creating the object each time
  var element = document.createElement('div');

  function decodeHTMLEntities (str) {
    if(str && typeof str === 'string') {
      // strip script/html tags
      str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
      str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
      element.innerHTML = str;
      str = element.textContent;
      element.textContent = '';
    }

    return str;
  }

  return decodeHTMLEntities;
})();

http://jsfiddle.net/LYteC/4/

要使用此函数,只需调用decodeEntities("&amp;")它,它将使用与 jQuery 版本相同的底层技术——但没有 jQuery 的开销,并且在清理输入中的 HTML 标签之后。有关如何过滤掉 HTML 标记的已接受答案,请参阅Mike Samuel 的评论

通过在您的项目中添加以下行,可以轻松地将此函数用作 jQuery 插件。

jQuery.decodeEntities = decodeEntities;
有人能告诉我什么 str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '') ; 做?
2021-03-10 03:30:50
注意:IE8 不支持 textContent,因此如果它仍然是您的目标浏览器之一,您必须找到其他解决方案。我只是浪费了一个小时试图弄清楚这一点,因为我们需要专门解码实体以弥补另一个 IE8 错误。
2021-03-18 03:30:50
@PoeHaH 它去除了所有 html 标签,包括开始和结束。
2021-03-22 03:30:50
小心取出 HTML 标签的那一行。您不应该在 HTML/XML 中使用正则表达式。多年来,博宾斯已经清楚地表明了这一点。
2021-03-23 03:30:50
@Qix 我不完全理解这里的问题。HTML/XML 当然不应该像人们经常做的那样“用正则表达式解析”。如果您要做的只是标记它,那么 AFAIK 正则表达式正是一个理想的解决方案。除非我遗漏了什么,完全剥离标签不应该需要词法分析之外的任何东西,因此在这里超越正则表达式没有任何好处。
2021-04-06 03:30:50

你可以尝试这样的事情:

var Title = $('<textarea />').html("Chris&apos; corner").text();
console.log(Title);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

JS小提琴

一个更具交互性的版本:

$('form').submit(function() {
  var theString = $('#string').val();
  var varTitle = $('<textarea />').html(theString).text();
  $('#output').text(varTitle);
  return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post">
  <fieldset>
    <label for="string">Enter a html-encoded string to decode</label>
    <input type="text" name="string" id="string" />
  </fieldset>
  <fieldset>
    <input type="submit" value="decode" />
  </fieldset>
</form>

<div id="output"></div>

JS小提琴

@chris 和 @david - 此代码创建一个空的(与 DOM 分离的)div 并将其设置为 innerHTML 并最终作为普通文本检索回来。它不是用 DIV 包围它,而是将它放在一个 div 中我强调了这一点,因为了解 jQuery 的工作原理至关重要。
2021-03-24 03:30:50
对于较旧的 jQuery 版本,这可能容易受到 XSS 攻击(在此处查看更多信息)。我建议改用他的图书馆您可以在类似问题的另一个答案中查看代码示例
2021-03-26 03:30:50
不要将它用于不受信任的数据,请参阅 Mike 在此处的评论:stackoverflow.com/questions/1147359/...
2021-04-02 03:30:50
只是插一句。这很容易受到 xss 攻击,试试吧!stackoverflow.com/questions/31282274/...
2021-04-04 03:30:50
酷的作品。所以只是好奇,$('div />') 用于在 varTitle 周围创建一个 <div> 元素?
2021-04-06 03:30:50

就像 Robert K 所说的那样,不要使用 jQuery.html().text() 来解码 html 实体,因为它是不安全的,因为用户输入永远不应该访问 DOM。阅读XSS以了解为什么这是不安全的。

而是尝试使用带有转义转义方法Underscore.js实用程序带库

_.escape(字符串)

逸出用于插入HTML,替换字符串&<>"`,和'字符。

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

_.unescape(字符串)

逃跑的对面,更换&amp;&lt;&gt;&quot;&#96;&#x27;与他们同行的转义。

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

要支持解码更多字符,只需复制 Underscore unescape方法并将更多字符添加到映射中。

@chovy,使用最新的 Underscore.js 版本 >= 1.4.2,你不会得到 TypeError。
2021-03-13 03:30:50
_.unescape仅适用于少数值所以像_.unescape('&raquo;')例如这样的东西只会返回"&raquo;"
2021-03-14 03:30:50
我喜欢这个答案,因为它不需要 DOM,现在谁可以保证在编写 javascript 时访问 DOM API?不幸的是,它只适用于列出的实体,并留下诸如   之类的东西。原封不动。
2021-03-15 03:30:50
请记住,它不会取消编码已编码的俄语或日语字符。例如 ハローワールド -> ハローワールド 不能用这个完成
2021-03-15 03:30:50
+1 用于使用源代码控制的库,而不是从顶部堆栈溢出答案中复制和粘贴一些随机代码。如果只有 javascript 标准库有这些类型的低级函数。
2021-03-31 03:30:50

原作者在这里回答

这是我最喜欢的解码 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>
这种技术有什么缺点吗?这似乎比上面的答案容易得多。
2021-03-15 03:30:50
即使 jquery 不可用或尚未加载,此方法也适用于任何地方,因为它是纯 javascript。
2021-03-16 03:30:50
@anthonygood 每次函数创建一个新对象(DOM 元素)
2021-03-20 03:30:50
下次@insign 请注明原作者或提供链接。stackoverflow.com/a/7394787
2021-04-01 03:30:50
@geauser 是的,完成
2021-04-09 03:30:50

这是一个不需要创建 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;
}
当您尝试在 javascript 中复制 htmlspecialchars_decode 时,这已完成。它不会假装复制 html_entity_decode。我发现关于这个话题有很多噪音和许多臃肿/不安全的方法。这是 Kip 和 Chris Jacob 提供的优秀编码解决方案的解码伴侣:stackoverflow.com/questions/1787322/...
2021-03-12 03:30:50
是的,所以你的解决方案是不完整的。OP 从来没有说过他们为什么要编码他们的 HTML 实体,所以如果你在这方面做出假设,它可能应该在答案中注明。
2021-03-23 03:30:50
您的答案对大多数 html 实体根本不起作用,将其扩展以包含它们将非常重复且容易出错。例如,每个日本汉字字符都有一个实体,其中有数千个。另外,到那时,如果您的答案比这里的其他一些答案慢,我不会感到惊讶,因为您要为每个要解码的字符串运行数千个替换和数千个正则表达式。
2021-03-28 03:30:50
当您对这些字符串进行编码时,这实际上取决于您的目的。如果您的目标是让它不通过诸如 < 或 > 之类的东西触发 HTML 处理,则完全没有必要通过字符实体语法对其他字符进行编码。大量的字符实体主要用作便利工具。我列出的实体是您必须转义的最低限度的实体,以避免数据与 HTML 混淆。[在下一条评论中继续]
2021-03-31 03:30:50
至于速度方面,运行多个正则表达式的好处。但是,当然,因为您将每个字符实体放入该代码的想法毫无意义,而且坦率地说,真的很愚蠢,所以这不是问题。然而,可以使用 | 生成正则表达式。首先字符并执行单个replace() 调用。我认为您必须对其进行基准测试以查看哪个更快,但我的直觉说它会更快使用 | 由于 Javascript 中的函数调用开销很高,因此使用了一个 replace()。
2021-03-31 03:30:50