我有一些与XML-RPC后端通信的JavaScript代码。 XML-RPC返回如下形式的字符串:

<img src='myimage.jpg'>

然而,当我使用JavaScript将字符串插入到HTML中时,它们会逐字呈现。我看到的不是图像,而是字符串:

<img src='myimage.jpg'>

我猜想HTML是通过XML-RPC通道转义的。

如何在JavaScript中解除字符串转义?我尝试了这个页面上的技巧,但没有成功:http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/

诊断这个问题的其他方法是什么?


当前回答

函数decodeHTMLContent(htmlText) { var txt = document.createElement("span"); 三种。innerHTML = htmlText; 返回txt.innerText; } var result = decodeHTMLContent('One &两个,三个“); console.log(结果);

其他回答

我在我的项目中使用了这个方法:受到其他答案的启发,但有一个额外的安全参数,在处理装饰字符时很有用

var decodeEntities=(function(){

    var el=document.createElement('div');
    return function(str, safeEscape){

        if(str && typeof str === 'string'){

            str=str.replace(/\</g, '&lt;');

            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, '&lt;');
        }
        return str;
    }
})();

它的可用性如下:

var label='safe <b> character &eacute;ntity</b>';
var safehtml='<div title="'+decodeEntities(label)+'">'+decodeEntities(label, true)+'</div>';

不是对你的问题的直接回应,但它不是更好为您的RPC返回一些结构(是XML或JSON或其他)与那些图像数据(在您的例子中的url)在该结构?

然后你可以在javascript中解析它,并使用javascript本身构建<img>。

你从RPC接收到的结构可能是这样的:

{"img" : ["myimage.jpg", "myimage2.jpg"]}

我认为这样更好,因为将来自外部源代码的代码注入您的页面看起来不太安全。想象一下,有人劫持了您的XML-RPC脚本,并在其中放入了一些您不想要的东西(甚至是一些javascript……)

如果你正在使用jQuery:

function htmlDecode(value){ 
  return $('<div/>').html(value).text(); 
}

否则,使用Strictly Software的Encoder对象,它有一个很棒的htmlDecode()函数。

当前投票最多的答案有从字符串中删除HTML的缺点。如果这不是你想要的(这当然不是问题的一部分),那么我建议使用正则表达式来查找HTML实体(/&[^;]*;/gmi),然后遍历匹配并转换它们。

function decodeHTMLEntities(str) { if (typeof str !== 'string') { return false; } var element = document.createElement('div'); return str.replace(/&[^;]*;/gmi, entity => { entity = entity.replace(/</gm, '&lt;'); element.innerHTML = entity; return element.textContent; }); } var encoded_str = `<b>&#8593; &#67;&#65;&#78;'&#84;&nbsp;&#72;&#65;&#67;&#75;&nbsp;&#77;&#69;,&nbsp;&#66;&#82;&#79;</b>`; var decoded_str = decodeHTMLEntities(encoded_str); console.log(decoded_str);

关于XSS攻击:

虽然innerHTML不执行<script>标签中的代码,但有可能在*事件属性中运行代码,因此用户传递的字符串可能会利用上面的正则表达式:

&<img src='asdfa' error='alert(`doin\' me a hack`)' />;

因此,有必要将任何<字符转换为它们的&lt;在将它们放入隐藏的div元素之前。

此外,为了覆盖我所有的基础,我将注意到,在全局作用域中定义的函数可以通过在控制台上重新定义它们来重写,因此使用const定义这个函数或将其放在非全局作用域中非常重要。

注意:以下示例中企图利用的漏洞会使堆栈片段编辑器混淆,因为它所做的预处理,所以您必须在浏览器的控制台中运行它,或者在它自己的文件中运行它才能查看结果。

var tests = [
  "here's a spade: &spades;!",
  "&<script>alert('hackerman')</script>;",
  "&<img src='asdfa' error='alert(`doin\' me a hack`)' />;",
  "<b>&#8593; &#67;&#65;&#78;'&#84;&nbsp;&#72;&#65;&#67;&#75;&nbsp;&#77;&#69;,&nbsp;&#66;&#82;&#79;</b>"
];

var decoded = tests.map(decodeHTMLEntities).join("\n");
console.log(decoded);

结果是:

here's a spade: ♠!
&<script>alert('hackerman')</script>;
&<img src='asdfa' error='alert(`doin' me a hack`)' />;
<b>↑ CAN'T HACK ME, BRO</b>

对于只说一句话的男人:

const htmlDecode = innerHTML => Object.assign(document.createElement('textarea'), {innerHTML}).value;

console.log(htmlDecode('Complicated - Dimitri Vegas &amp; Like Mike'));