小智 434
安全说明:使用此答案(保存在下面的原始格式中)可能会在您的应用程序中引入XSS漏洞.你不应该使用这个答案.阅读lucascaro的答案,解释这个答案中的漏洞,并使用答案中的方法或Mark Amery的答案.
实际上,试试吧
var decoded = $("<div/>").html(encodedStr).text();
Run Code Online (Sandbox Code Playgroud)
luc*_*aro 202
没有任何jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'Run Code Online (Sandbox Code Playgroud)
这与接受的答案类似,但可以安全地使用不受信任的用户输入.
正如Mike Samuel所指出的那样,使用一个不受信任的用户输入<div>代替<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)">')Run Code Online (Sandbox Code Playgroud)
但是,这种攻击是不可能的,<textarea>因为没有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)">'))Run Code Online (Sandbox Code Playgroud)
警告:这样做使用jQuery的
.html()和.val()方法,而不是使用.innerHTML和.value也是不安全*的jQuery的一些版本中,使用时甚至textarea.这是因为旧版本的jQuery会故意并明确地评估传递给字符串的脚本.html().因此这样的代码在jQuery 1.8中显示了一个警告:
//<!-- CDATA
// Shows alert
$("<textarea>")
.html("<script>alert(1337);</script>")
.text();
//-->Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>Run Code Online (Sandbox Code Playgroud)
*感谢Eru Penkman捕获此漏洞.
Ala*_*ett 80
就像Mike Samuel所说,不要使用jQuery.html().text()来解码html实体,因为它不安全.
相反,使用来自@ VyvIT评论的Mustache.js或decodeEntities等模板渲染器.
Underscore.js公用事业带库带有escape和unescape方法,但它们都没有用户输入的安全:
Can*_*var 28
我认为你混淆了文本和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>
Run Code Online (Sandbox Code Playgroud)
第一个按钮写道:这是一个HTML内容.
第二个按钮写道:这是一个<B> HTML </ B>内容.
顺便说一下,你可以看到我在jQuery插件中找到的插件 - HTML解码和编码,用于编码和解码HTML字符串.
Ron*_*ndo 26
这个问题受到'with jQuery'的限制,但它可能有助于一些人知道在这里的最佳答案中给出的jQuery代码在下面做了以下...这有或没有jQuery:
function decodeEntities(input) {
var y = document.createElement('textarea');
y.innerHTML = input;
return y.value;
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ery 18
您可以使用他的库,可从https://github.com/mathiasbynens/he获得
例:
console.log(he.decode("Jörg & Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
Run Code Online (Sandbox Code Playgroud)
我向图书馆的作者提出了一个问题,即是否有任何理由在客户端代码中使用此库以支持此处和其他地方的其他答案中<textarea>提供的黑客.他提供了一些可能的理由:
如果您正在使用node.js服务器端,则使用用于HTML编码/解码的库可以为您提供一个可在客户端和服务器端工作的单一解决方案.
某些浏览器的实体解码算法存在错误或缺少对某些命名字符引用的支持.例如,Internet Explorer将 正确解码和呈现非中断空格(),但是通过DOM元素的innerText属性将它们报告为普通空格而不是非中断空格,从而打破了<textarea>黑客攻击(虽然只是一种次要的方式).此外,IE 8和9根本不支持 HTML 5中添加的任何新命名字符引用.他的作者还在http://mathias.html5.org/tests/html上对命名字符引用支持进行了测试./ named-character-references /.在IE 8中,它报告了超过一千个错误.
如果你想要与实体解码相关的浏览器错误和/或能够处理所有命名的字符引用,你就无法摆脱<textarea>黑客攻击.你需要像他这样的图书馆.
他只是觉得用这种方式做事就不那么黑了.
小智 17
编码:
$("<textarea/>").html('<a>').html(); // return '<a>'
Run Code Online (Sandbox Code Playgroud)
解码:
$("<textarea/>").html('<a>').val() // return '<a>'
Run Code Online (Sandbox Code Playgroud)