如何使用 jQuery 解码字符串中的 HTML 实体?
如何使用 jQuery 解码 HTML 实体?
安全说明:使用此答案(保留在下面的原始形式)可能会在您的应用程序中引入XSS 漏洞。你不应该使用这个答案。阅读lucascaro 的答案以了解此答案中的漏洞,并改用该答案或Mark Amery 的答案中的方法。
其实试试
var encodedStr = "This is fun & stuff";
var decoded = $("<div/>").html(encodedStr).text();
console.log(decoded);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div/>
没有任何 jQuery:
function decodeEntities(encodedString) {
  var textArea = document.createElement('textarea');
  textArea.innerHTML = encodedString;
  return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
这与接受的答案类似,但可以安全地用于不受信任的用户输入。
类似方法中的安全问题
正如Mike Samuel所指出的,使用不受信任的用户输入<div>而不是使用 a来执行此<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)">')
然而,这种攻击是不可能针对 a 的,<textarea>因为没有允许 a 的内容的 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的
.html()和.val()方法,而不是使用.innerHTML和.value也的jQuery的某些版本不安全*,使用时甚至textarea。这是因为旧版本的 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>
* 感谢Eru Penkman捕获此漏洞。
就像 Mike Samuel 所说的那样,不要使用 jQuery.html().text() 来解码 html 实体,因为它是不安全的。
相反,使用来自 @VyvIT 评论的Mustache.js或decodeEntities等模板渲染器。
Underscore.js实用程序带库带有escape和unescape方法,但它们对于用户输入并不安全:
我认为您混淆了文本和 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 decode and encode,它对HTML字符串进行编码和解码。
该问题受到“使用 jQuery”的限制,但它可能有助于某些人知道此处最佳答案中给出的 jQuery 代码在下面执行以下操作……这在使用或不使用 jQuery 的情况下都有效:
function decodeEntities(input) {
  var y = document.createElement('textarea');
  y.innerHTML = input;
  return y.value;
}