Javascript中的Unescape HTML实体?
我有一些与XML-RPC后端通信的Javascript代码。 XML-RPC返回以下格式的字符串:Javascript中的Unescape HTML实体?,javascript,html,escaping,xml-rpc,Javascript,Html,Escaping,Xml Rpc,我有一些与XML-RPC后端通信的Javascript代码。 XML-RPC返回以下格式的字符串: <img src='myimage.jpg'> 然而,当我使用Javascript将字符串插入HTML时,它们会按字面意思呈现。我没有看到图像,我只是看到了字符串: <img src='myimage.jpg'> 我猜HTML是通过XML-RPC通道转义的 如何在Javascript中取消对字符串的扫描?我尝试了本页上的技巧,但没有成功: 诊断此问题的其他方法有
<img src='myimage.jpg'>
然而,当我使用Javascript将字符串插入HTML时,它们会按字面意思呈现。我没有看到图像,我只是看到了字符串:
<img src='myimage.jpg'>
我猜HTML是通过XML-RPC通道转义的
如何在Javascript中取消对字符串的扫描?我尝试了本页上的技巧,但没有成功:
诊断此问题的其他方法有哪些?编辑:您应该使用DOMParser API,因为我编辑了之前的答案,因为发布的函数引入了安全漏洞 下面的代码片段是旧答案的代码,稍加修改:使用
textarea
而不是div
可以减少XSS漏洞,但在IE9和Firefox中仍然存在问题
function htmlDecode(input){
var e = document.createElement('textarea');
e.innerHTML = input;
// handle case of empty input
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
htmlDecode("<img src='myimage.jpg'>");
// returns "<img src='myimage.jpg'>"
函数htmlDecode(输入){
var e=document.createElement('textarea');
e、 innerHTML=输入;
//处理空输入的情况
返回e.childNodes.length==0?“:e.childNodes[0].nodeValue;
}
htmlDecode(“imgsrc='myimage.jpg'”);
//返回“”
基本上,我以编程方式创建DOM元素,将编码的HTML分配给其innerHTML,并从innerHTML插入时创建的文本节点检索nodeValue。因为它只是创建一个元素,但从不添加它,所以不会修改任何站点HTML
它将跨浏览器(包括旧浏览器)工作,并接受所有
编辑:该代码的旧版本不能在IE上使用空白输入,这是可以证明的(在IE中查看)。上述版本适用于所有输入
更新:这似乎不适用于大字符串,并且它还引入了一个安全漏洞,请参阅注释。不是对您的问题的直接回答,但是您的RPC是否最好在该结构中使用这些图像数据(示例中的URL)返回一些结构(XML或JSON或其他格式) 然后您可以在javascript中解析它,并使用javascript本身构建
从RPC接收的结构可能如下所示:
{"img" : ["myimage.jpg", "myimage2.jpg"]}
我认为这样更好,因为将来自外部源代码的代码注入到您的页面看起来不太安全。想象有人劫持了您的XML-RPC脚本,并将您不想要的东西(甚至是一些javascript…)放入其中,如果您正在使用jQuery:
function htmlDecode(value){
return $('<div/>').html(value).text();
}
函数htmlDecode(值){
返回$('').html(value.text();
}
否则,请使用,它具有出色的
htmlDecode()
功能。您需要解码所有编码的HTML实体还是只解码&代码>本身
如果您只需要处理&代码>然后您可以执行以下操作:
var decoded = encoded.replace(/&/g, '&');
如果需要解码所有HTML实体,则可以不使用jQuery:
var elem = document.createElement('textarea');
elem.innerHTML = encoded;
var decoded = elem.value;
请注意下面Mark的评论,这些评论强调了本答案早期版本中的安全漏洞,并建议使用textarea
而不是div
来抵御潜在的XSS漏洞。无论您是使用jQuery还是普通JavaScript,都存在这些漏洞。Chris answer很漂亮,但如果值未定义,则会失败。只需简单的改进即可使其坚固:
function htmlDecode(value) {
return (typeof value === 'undefined') ? '' : $('<div/>').html(value).text();
}
函数htmlDecode(值){
return(typeof value==='undefined')?'':$('').html(value.text();
}
元素。innerText
也起作用。首先在身体的某个地方创建一个
接下来,将要解码为innerHTML的字符串分配给以下对象:
document.getElementById("decodeIt").innerHTML=stringtodecode
最后,
stringtodecode=document.getElementById("decodeIt").innerText
以下是总体代码:
var stringtodecode="<B>Hello</B> world<br>";
document.getElementById("decodeIt").innerHTML=stringtodecode;
stringtodecode=document.getElementById("decodeIt").innerText
var stringtodecode=“你好世界
”;
document.getElementById(“decodeIt”).innerHTML=stringtodecode;
stringtodecode=document.getElementById(“decodeIt”).innerText
var htmlEnDeCode=(函数(){
var charToEntityRegex,
entityToCharRegex,
宪章实体,
全托卡尔;
函数resetCharacterEntities(){
图表实体={};
entityToChar={};
//添加默认设置
addCharacterEntities({
“&;”:“&;”,
'' : '>',
“”:“CMS”答案可以正常工作,除非您要取消scape的HTML非常长,超过65536个字符。因为在Chrome中,内部HTML会被拆分为多个子节点,每个子节点的长度最多为65536个,您需要连接它们。此函数也适用于非常长的字符串:
function unencodeHtmlContent(escapedHtml) {
var elem = document.createElement('div');
elem.innerHTML = escapedHtml;
var result = '';
// Chrome splits innerHTML into many child nodes, each one at most 65536.
// Whereas FF creates just one single huge child node.
for (var i = 0; i < elem.childNodes.length; ++i) {
result = result + elem.childNodes[i].nodeValue;
}
return result;
}
函数unencodeHtmlContent(转义HTML){
var elem=document.createElement('div');
elem.innerHTML=转义HTML;
var结果=“”;
//Chrome将innerHTML拆分为多个子节点,每个节点最多65536个。
//而FF只创建一个巨大的子节点。
对于(变量i=0;i
有关详细信息,请参见关于innerHTML
max length的回答:Matthias Bynens为此提供了一个库:
例如:
console.log(
he.decode("Jörg & Jürgen rocked to & fro ")
);
// Logs "Jörg & Jürgen rocked to & fro"
我建议,与设置元素的HTML内容然后读回其文本内容的黑客相比,更倾向于使用它。这种方法可以工作,但具有欺骗性的危险性,如果在不可信的用户输入上使用,则会带来XSS机会
如果你真的不忍心在库中加载,你可以使用textarea
中描述的hack来解决一个几乎重复的问题,与已经提出的各种类似方法不同,它没有我所知道的安全漏洞:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
但请注意我在链接答案中列出的影响类似方法的安全问题!这种方法是一种黑客行为,以及将来对文本区域
的允许内容的更改(或特定浏览器中的错误)可能导致依赖它的代码某天突然出现XSS漏洞。这里给出的大多数答案都有一个巨大的缺点:如果
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
htmlDecode("<img src='dummy' onerror='alert(/xss/)'>");
var map = {amp: '&', lt: '<', gt: '>', quot: '"', '#039': "'"}
str = str.replace(/&([^;]+);/g, (m, c) => map[c])
var decodeEntities=(function(){
var el=document.createElement('div');
return function(str, safeEscape){
if(str && typeof str === 'string'){
str=str.replace(/\</g, '<');
el.innerHTML=str;
if(el.innerText){
str=el.innerText;
el.innerText='';
}
else if(el.textContent){
str=el.textContent;
el.textContent='';
}
if(safeEscape)
str=str.replace(/\</g, '<');
}
return str;
}
})();
var label='safe <b> character éntity</b>';
var safehtml='<div title="'+decodeEntities(label)+'">'+decodeEntities(label, true)+'</div>';
const htmlDecode = innerHTML => Object.assign(document.createElement('textarea'), {innerHTML}).value;
console.log(htmlDecode('Complicated - Dimitri Vegas & Like Mike'));
function htmlDecode(html) {
var textarea = document.createElement("textarea");
html= html.replace(/\r/g, String.fromCharCode(0xe000)); // Replace "\r" with reserved unicode character.
textarea.innerHTML = html;
var result = textarea.value;
return result.replace(new RegExp(String.fromCharCode(0xe000), 'g'), '\r');
}
htmlDecode('<& >'); // returns "<& >" with non-breaking space.
htmlDecode(' '); // returns " "
htmlDecode('<img src="dummy" onerror="alert(\'xss\')">'); // Does not execute alert()
htmlDecode('\r\n') // returns "\r\n", doesn't lose the \r like other solutions.
function unescapeHtml(html) {
var el = document.createElement('div');
return html.replace(/\&[#0-9a-z]+;/gi, function (enc) {
el.innerHTML = enc;
return el.innerText
});
}
var x = "test &";
> undefined
$.parseHTML(x)[0].textContent
> "test &"
import unescape from 'lodash/unescape';
const str = unescape('fred, barney, & pebbles');
var stringtodecode="<B>Hello</B> world<br>";
document.getElementById("decodeIt").innerHTML=stringtodecode;
stringtodecode=document.getElementById("decodeIt").innerText
var modal = document.getElementById('demodal');
$('#ampersandcontent').text(replaceAll(data[0],"&", "&"));
window.htmlentities = {
/**
* Converts a string to its html characters completely.
*
* @param {String} str String with unescaped HTML characters
**/
encode : function(str) {
var buf = [];
for (var i=str.length-1;i>=0;i--) {
buf.unshift(['&#', str[i].charCodeAt(), ';'].join(''));
}
return buf.join('');
},
/**
* Converts an html characterSet into its original character.
*
* @param {String} str htmlSet entities
**/
decode : function(str) {
return str.replace(/&#(\d+);/g, function(match, dec) {
return String.fromCharCode(dec);
});
}
};
var encodedStr = 'hello & world';
var parser = new DOMParser;
var dom = parser.parseFromString(
'<!doctype html><body>' + encodedStr,
'text/html');
var decodedString = dom.body.textContent;
console.log(decodedString);
const STANDARD_HTML_ENTITIES = {
nbsp: String.fromCharCode(160),
amp: "&",
quot: '"',
lt: "<",
gt: ">"
};
const replaceHtmlEntities = plainTextString => {
return plainTextString
.replace(/&#(\d+);/g, (match, dec) => String.fromCharCode(dec))
.replace(
/&(nbsp|amp|quot|lt|gt);/g,
(a, b) => STANDARD_HTML_ENTITIES[b]
);
};
import {unescape} from 'html-escaper';
unescape('escaped string');