我该如何使用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/>
$("<div/>").html('<img src="http://www.google.com/images/logos/ps_logo2.png" onload=alert(1337)>')
。在Firefox或Safari中,它会触发警报。 - Mike Samuel$($.parseHTML(item.title.rendered)).text()
。 - Pranesh Janarthanan没有任何jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
正如Mike Samuel所指出的,使用
decodedString = textArea.value;
textArea.remove();
return decodedString;
- Wernerif ('remove' in Element.prototype) textArea.remove();
- Werner$("<div />").html(string).text()
会执行提供的字符串中的任何JavaScript,我怀疑这就是导致你问题的原因。应该将被接受的答案更新为这个。 - jbowman像Mike Samuel所说的那样,不要使用jQuery.html().text()来解码HTML实体,因为它是不安全的。
相反地,使用模板渲染器,例如Mustache.js或@VyvIT评论中提到的decodeEntities。
Underscore.js实用工具库带有转义和取消转义方法,但对于用户输入并不安全:
unescape
。 - lethal-guitar_.unescape("'")
的结果只是 '
而不是单引号。我是否遗漏了什么,或者underscore不能像http://www.w3schools.com/tags/ref_entities.asp所示的那样转义HTML实体代码? - Jason Axelsonescape
和unescape
方法...对于用户输入不安全”。这是什么意思?在我看来,这听起来像无稽之谈,但也许我漏掉了什么——你能澄清一下吗? - Mark Amery_.unescape("<img src=fake onerror=alert('boo!')>")
,但它没有弹出任何警报。我已经尝试在控制台中运行它,也将其放入我的 JS 文件中。结果相同。 - Vivek Athalye我认为你混淆了文本和HTML方法。看一下这个例子,如果你将元素的inner 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字符串进行编码和解码。
这个问题受到“使用jQuery”的限制,但是对一些人有帮助的是,最佳答案中给出的jQuery代码在下面执行了以下操作... 这可以与或没有jQuery一起工作:
function decodeEntities(input) {
var y = document.createElement('textarea');
y.innerHTML = input;
return y.value;
}
编码:
$("<textarea/>").html('<a>').html(); // return '<a>'
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea/>
解码:
$("<textarea/>").html('<a>').val() // return '<a>'
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea/>
console.log(he.decode("Jörg & Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
我向库的作者提出了质疑,询问在客户端代码中是否有任何理由使用这个库,而不是使用其他答案中和其他地方提供的<textarea>
hack。他提供了一些可能的理由:
如果你使用node.js服务器端,使用一个HTML编码/解码库可以为你提供一个单一的解决方案,既适用于客户端又适用于服务器端。
一些浏览器的实体解码算法存在错误或缺少对一些命名字符引用的支持。例如,Internet Explorer虽然可以正确解码和呈现非断空格(
),但是在通过DOM元素的innerText
属性报告它们时,会将它们报告为普通空格而不是非断空格,这破坏了<textarea>
的hack(尽管只是轻微的)。此外,IE 8和9根本不支持HTML5中添加的任何新的命名字符引用。作者还在http://mathias.html5.org/tests/html/named-character-references/上托管了一个命名字符引用支持测试。在IE 8中,它报告了一千多个错误。
如果你想免受与实体解码相关的浏览器错误影响,或者想能够处理全部的命名字符引用范围,那么你不能仅仅使用<textarea>
的hack;你需要像he这样的库。
他只是感觉这种方式做事情不那么hacky。
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库中的一个函数,它将返回一个数组,其中包含有关给定字符串的一些详细信息。
在某些情况下,字符串很大,因此该函数将把内容分成许多索引。
要获取所有索引数据,您应该转到任何索引,然后访问名为"wholeText"的索引。
我选择索引0,因为它适用于所有情况(小字符串或大字符串)。
使用
myString = myString.replace( /\&/g, '&' );
因为显然JavaScript没有处理实体的本地库,而且我在各种扩展JavaScript的框架的搜索结果中也没有找到任何与之相关的内容,所以最简单的方法是在服务器端进行处理。
搜索“JavaScript HTML实体”,你可能会找到一些专门用于此目的的库,但它们可能都是基于上述逻辑构建的-逐个实体替换。