我有一些与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/

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


当前回答

// decode-html.js v1
function decodeHtml(html) {
    const textarea = document.createElement('textarea');
    textarea.innerHTML = html;
    const decodedHtml = textarea.textContent;
    textarea.remove();
    return decodedHtml;
};

// encode-html.js v1
function encodeHtml(html) {
    const textarea = document.createElement('textarea');
    textarea.textContent = html;
    const encodedHtml = textarea.innerHTML;
    textarea.remove();
    return encodedHtml;
};

// example of use:
let htmlDecoded = 'one & two & three';
let htmlEncoded = 'one &amp; two &amp; three';

console.log(1, htmlDecoded);
console.log(2, encodeHtml(htmlDecoded));

console.log(3, htmlEncoded);
console.log(4, decodeHtml(htmlEncoded));

其他回答

克里斯的回答很好,很优雅,但如果值未定义就失败了。简单的改进就能让它稳固:

function htmlDecode(value) {
   return (typeof value === 'undefined') ? '' : $('<div/>').html(value).text();
}

如果你正在寻找它,像我一样-同时有一个很好的和安全的JQuery方法。

https://api.jquery.com/jquery.parsehtml/

你可以用f.ex。在控制台中输入以下内容:

var x = "test &amp;";
> undefined
$.parseHTML(x)[0].textContent
> "test &"

因此$. parsehtml (x)返回一个数组,如果文本中有HTML标记,则返回数组。Length大于1。

元素。innerText也可以做到这一点。

我知道这里有很多好的答案,但由于我实现了一个有点不同的方法,我想分享一下。

这段代码是一种非常安全的安全方法,因为转义处理程序依赖于浏览器,而不是函数。因此,如果将来发现新的漏洞,将覆盖此解决方案。

const decodeHTMLEntities = text => {
    // Create a new element or use one from cache, to save some element creation overhead
    const el = decodeHTMLEntities.__cache_data_element 
             = decodeHTMLEntities.__cache_data_element 
               || document.createElement('div');
    
    const enc = text
        // Prevent any mixup of existing pattern in text
        .replace(/⪪/g, '⪪#')
        // Encode entities in special format. This will prevent native element encoder to replace any amp characters
        .replace(/&([a-z1-8]{2,31}|#x[0-9a-f]+|#\d+);/gi, '⪪$1⪫');

    // Encode any HTML tags in the text to prevent script injection
    el.textContent = enc;

    // Decode entities from special format, back to their original HTML entities format
    el.innerHTML = el.innerHTML
        .replace(/⪪([a-z1-8]{2,31}|#x[0-9a-f]+|#\d+)⪫/gi, '&$1;')
        .replace(/#⪫/g, '⪫');
   
    // Get the decoded HTML entities
    const dec = el.textContent;
    
    // Clear the element content, in order to preserve a bit of memory (it is just the text may be pretty big)
    el.textContent = '';

    return dec;
}

// Example
console.log(decodeHTMLEntities("<script>alert('&awconint;&CounterClockwiseContourIntegral;&#x02233;&#8755;⪪#x02233⪫');</script>"));
// Prints: <script>alert('∳∳∳∳⪪##x02233⪫');</script>

顺便说一下,我选择使用字符⪪和⪫,因为它们很少被使用,因此通过匹配它们影响性能的几率显著降低。

您可以使用Lodash的unescape / escape功能https://lodash.com/docs/4.17.5#unescape

import unescape from 'lodash/unescape';

const str = unescape('fred, barney, &amp; pebbles');

STR将变成“弗雷德、巴尼和卵石”