Javascript中的Unescape HTML实体?
我有一些与XML-RPC后端进行通信的Javascript代码。 XML-RPC返回以下格式的string:
<img src='myimage.jpg'>
但是,当我使用Javascript将string插入到HTML中时,它们字面呈现。 我没有看到一个图像,我从字面上看string:
<img src='myimage.jpg'>
我的猜测是HTML正在通过XML-RPC通道转义。
我怎样才能避免在Javascript中的string? 我尝试了这个页面上的技巧,失败了: http : //paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/
什么是其他方法来诊断这个问题?
我使用以下方法:
function htmlDecode(input){ var e = document.createElement('div'); 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'>"
基本上我编程创build一个DOM元素,将编码的HTML分配给它的innerHTML,并从innerHTML插入中创build的文本节点检索nodeValue。 由于它只是创build一个元素,但从来没有添加它,没有网站的HTML被修改。
它将跨浏览器(包括旧浏览器)并接受所有HTML字符实体 。
编辑:这个代码的旧版本不能在空白input的IE浏览器上工作,如jsFiddle (在IE浏览器中查看)certificate。 以上版本适用于所有input。
更新:出现这不适用于大string,它也引入了安全漏洞,请参阅注释。
这里给出的大多数答案都有一个巨大的缺点:如果你试图转换的string不被信任,那么你将最终得到一个跨站点脚本(XSS)漏洞 。 对于接受的答案中的function,请考虑以下内容:
htmlDecode("<img src='dummy' onerror='alert(/xss/)'>");
这里的string包含一个非转义的HTML标记,所以不用解码任何东西, htmlDecode
函数将实际运行在string内部指定的JavaScript代码。
这可以通过使用所有现代浏览器支持的DOMParser来避免:
function htmlDecode(input) { var doc = new DOMParser().parseFromString(input, "text/html"); return doc.documentElement.textContent; } // This returns "<img src='myimage.jpg'>" htmlDecode("<img src='myimage.jpg'>"); // This returns "" htmlDecode("<img src='dummy' onerror='alert(/xss/)'>");
这个函数保证不运行任何JavaScript代码作为一个副作用。 任何HTML标签将被忽略,只有文本内容将被返回。
兼容性说明 :使用DOMParser
parsingHTML至less需要Chrome 30,Firefox 12,Opera 17,Internet Explorer 10,Safari 7.1或Microsoft Edge。 因此,所有没有支持的浏览器都已经过了他们的EOL,而到了2017年,偶尔还能看到的只有Internet Explorer和Safari版本(通常这些浏览器还不够多)。
如果你使用jQuery:
function htmlDecode(value){ return $('<div/>').html(value).text(); }
否则,使用Strictly Software的编码器对象 ,它有一个很好的htmlDecode()
函数。
克里斯的回答是很好,优雅,但如果价值是未定义的,它会失败。 只是简单的改进使其坚实:
function htmlDecode(value) { return (typeof value === 'undefined') ? '' : $('<div/>').html(value).text(); }
CMS的答案工作正常,除非你想要unescape的HTML非常长,超过65536字符。 因为在Chrome浏览器中,内部的HTML被分割成多个子节点,每个子节点最多只有65536个,你需要连接它们。 这个函数也适用于很长的string:
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; }
有关更多信息,请参阅有关innerHTML
最大长度的答案: https : //stackoverflow.com/a/27545633/694469
不是对你的问题的直接回应,但是对于你的RPC来说,在这个结构里面用那些图像数据(你的例子中的url)返回一些结构(不pipe是XML还是JSON或其他)呢?
然后,你可以parsing它在你的JavaScript和build立使用JavaScript本身的<img>
。
从RPC收到的结构可能如下所示:
{"img" : ["myimage.jpg", "myimage2.jpg"]}
我认为这样做更好,因为将来自外部源的代码注入到页面中看起来不太安全。 想象一个人劫持你的XML-RPC脚本,并把你不想在那里的东西(甚至一些javascript …)
这是一个更好的:
String::decode = -> $('<textarea />').html(this).text()
使用:
"<img src='myimage.jpg'>".decode();
来自: HTML实体解码
诀窍是使用浏览器的力量解码特殊的HTML字符,但不允许浏览器执行的结果,如果它是实际的HTML …此函数使用正则expression式来识别和replace编码的HTML字符,一个字符一次。
function unescapeHtml(html) { var el = document.createElement('div'); return html.replace(/\&[#0-9a-z]+;/gi, function (enc) { el.innerHTML = enc; return el.innerText }); }
我在我的项目中使用这个:受其他答案的启发,但有一个额外的安全参数,可以在处理装饰字符时很有用
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>';
所有其他的答案在这里都有问题。
document.createElement('div')方法(包括那些使用jQuery的)执行任何传递给它的JavaScript(一个安全问题),并且DOMParser.parseFromString()方法修剪空白。 这里是一个纯粹的JavaScript解决scheme,没有问题:
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'); }
TextArea专门用于避免执行js代码。 它通过这些:
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.