Answers:
安全说明:使用此答案(下面以其原始形式保留)可能会在您的应用程序中引入XSS漏洞。您不应该使用此答案。阅读lucascaro的答案以获取对该答案中漏洞的解释,然后使用该答案或Mark Amery的答案中的方法。
其实试试看
var decoded = $("<div/>").html(encodedStr).text();
$("<div/>").html('<img src="http://www.google.com/images/logos/ps_logo2.png" onload=alert(1337)>')
。在Firefox或Safari中,它会触发警报。
str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/g, "")
或类似的东西。
没有任何jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
这与已接受的答案类似,但是可以安全地用于不受信任的用户输入。
正如Mike Samuel所指出的那样,使用x<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)">')
但是,针对a的攻击是不可能的,<textarea>
因为没有HTML元素被允许为a的内容<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捕获此漏洞。
decodedString = textArea.value;
textArea.remove();
return decodedString;
if ('remove' in Element.prototype) textArea.remove();
$("<div />").html(string).text()
将执行提供的字符串中的所有JavaScript,我怀疑这是引起您问题的原因。接受的答案应更新为此。
就像Mike Samuel所说的那样,不要使用jQuery.html()。text()来解码html实体,因为这样做是不安全的。
相反,请使用模板渲染器(例如Mustache.js或@VyvIT注释中的encodeEntities)。
Underscore.js实用程序带库带有escape
和unescape
方法,但是对于用户输入而言,它们并不安全:
unescape
顺便说一句,他们现在包括在文档中。
_.unescape("'")
结果只是“&#39;” 而不是单引号。有什么我想念的东西吗?或者下划线不能逃脱到HTML实体代码,如下所示:w3schools.com/tags/ref_entities.asp
escape
和unescape
方法...对于用户输入而言并不安全”。这是什么意思 听起来对我来说是胡说八道,但也许我缺少了一些东西-您能澄清一下吗?
_.unescape("<img src=fake onerror=alert('boo!')>")
(在Chrome / FF / IE中)。但是它没有显示任何警报。在控制台中进行了尝试,并将其放入我的JS文件中。结果相同。
我认为您在混淆文本和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解码和编码,可以对 HTML字符串进行编码和解码。
您可以使用he库,该库可从https://github.com/mathiasbynens/he获得
例:
console.log(he.decode("Jörg & Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
我质疑图书馆的作者是否有任何理由在客户端代码中使用此图书馆,以支持此处和其他地方的其他答案中<textarea>
提供的技巧。他提供了一些可能的理由:
如果您在服务器端使用node.js,则使用用于HTML编码/解码的库可为您提供一个在客户端和服务器端均可使用的解决方案。
某些浏览器的实体解码算法存在错误或缺少对某些命名字符引用的支持。例如,Internet Explorer将
正确解码和渲染不间断空格(),但将它们报告为普通空间,而不是通过DOM元素的innerText
属性将其报告为不间断空格,从而打破了<textarea>
hack(尽管仅是次要的方式)。此外,IE 8和9根本不支持 HTML 5中添加的任何新的命名字符引用。他的作者还在http://mathias.html5.org/tests/html上托管了对命名字符引用支持的测试。/ named-character-references /。在IE 8中,它报告超过一千个错误。
如果您想避免与实体解码相关的浏览器错误和/或能够处理所有命名字符引用,则无法逃脱<textarea>
;你需要像他这样的图书馆。
他真是个好主意,感觉像这样做事不那么hacky。
编码:
$("<textarea/>").html('<a>').html(); // return '<a>'
解码:
$("<textarea/>").html('<a>').val() // return '<a>'
我只需要一个HTML实体字符(⇓)作为HTML按钮的值即可。HTML代码从浏览器开始就看起来不错:
<input type="button" value="Embed & Share ⇓" id="share_button" />
现在,我添加了一个开关,该开关也应显示字符。这是我的解决方案
$("#share_button").toggle(
function(){
$("#share").slideDown();
$(this).attr("value", "Embed & Share " + $("<div>").html("⇑").text());
}
这将再次在按钮中显示⇓。我希望这可以帮助某人。
"Embed & Share \u21d1"
),或者更好的方法是,"Embed & Share ⇑"
只要您能够以UTF-8(或UTF-16或任何其他支持⇑字符的编码)来提供脚本。使用DOM元素解析HTML实体只是将任意的unicode字符烘焙到JavaScript字符串中,是一种狡猾且富有创意的方法,会让Rube Goldberg感到骄傲,但这不是一个好习惯;unicode转义使用专门用于处理此用例的语言。
您必须为html实体创建自定义函数:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}
假设您在String下面。
我们的豪华客舱温暖,舒适,舒适。自在
var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text(); // Now,decode html entities in your variable i.e
str并分配回
标签。
而已。
扩展一个String类:
String::decode = ->
$('<textarea />').html(this).text()
并用作方法:
"<img src='myimage.jpg'>".decode()
尝试这个 :
var htmlEntities = "<script>alert('hello');</script>";
var htmlDecode =$.parseHTML(htmlEntities)[0]['wholeText'];
console.log(htmlDecode);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
parseHTML是Jquery库中的Function,它将返回一个数组,其中包含有关给定String的一些详细信息。
在某些情况下,字符串很大,因此该函数会将内容分为许多索引。
并获取所有索引数据,您应该转到任何索引,然后访问称为“ wholeText”的索引。
我选择索引0是因为它在所有情况下都适用(小字符串或大字符串)。
另外,这里还有一个图书馆。
在这里,https://cdnjs.com/libraries/he
npm install he //using node.js
<script src="js/he.js"></script> //or from your javascript directory
用法如下...
//to encode text
he.encode('© Ande & Nonso® Company LImited 2018');
//to decode the
he.decode('© Ande & Nonso® Company Limited 2018');
干杯。
要使用jQuery解码HTML实体,只需使用以下功能:
function html_entity_decode(txt){
var randomID = Math.floor((Math.random()*100000)+1);
$('body').append('<div id="random'+randomID+'"></div>');
$('#random'+randomID).html(txt);
var entity_decoded = $('#random'+randomID).html();
$('#random'+randomID).remove();
return entity_decoded;
}
如何使用:
Javascript:
var txtEncoded = "á é í ó ú";
$('#some-id').val(html_entity_decode(txtEncoded));
HTML:
<input id="some-id" type="text" />
最简单的方法是为您的元素设置类选择器,然后使用以下代码:
$(function(){
$('.classSelector').each(function(a, b){
$(b).html($(b).text());
});
});
不需要了!
我遇到了这个问题,并找到了明确的解决方案,并且效果很好。