代码之家  ›  专栏  ›  技术社区  ›  Art

在JavaScript中解码回(&B)

  •  199
  • Art  · 技术社区  · 14 年前

    我有一些与XML-RPC后端通信的Javascript代码。

    <img src='myimage.jpg'>
    

    <img src='我的图像.jpg'>
    

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

    如何在Javascript中取消显示字符串?我尝试了这一页上的技巧,但没有成功: http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/

    诊断问题的其他方法有哪些?

    12 回复  |  直到 15 年前
        1
  •  190
  •   Wladimir Palant    5 年前

    编辑: Wladimir suggests ,我编辑了以前的答案,因为发布的函数引入了安全漏洞。

    下面的代码片段是旧答案的代码,稍作修改:使用 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("&lt;img src='myimage.jpg'&gt;"); 
    // returns "<img src='myimage.jpg'>"
    

    基本上,我以编程方式创建DOM元素,将编码的HTML分配给其innerHTML,并从innerHTML插入时创建的文本节点检索nodeValue。因为它只是创建一个元素,但从不添加它,所以不会修改任何站点HTML。

    它可以跨浏览器(包括旧的浏览器)工作并接受所有 HTML Character Entities .

    编辑:这段代码的旧版本在输入为空的IE上不起作用 here on jsFiddle (在IE中查看)。以上版本适用于所有输入。

    更新:这似乎不适用于大字符串,它还引入了 ,见注释。

        2
  •  447
  •   vsync    5 年前

    Cross-Site Scripting (XSS) vulnerability . 对于中的函数 accepted answer ,请考虑以下事项:

    htmlDecode("<img src='dummy' onerror='alert(/xss/)'>");
    

    这里的字符串包含一个未转义的HTML标记,因此 htmlDecode 函数将实际运行字符串中指定的JavaScript代码。

    DOMParser 中支持的 all modern browsers

    function htmlDecode(input) {
      var doc = new DOMParser().parseFromString(input, "text/html");
      return doc.documentElement.textContent;
    }
    
    console.log(  htmlDecode("&lt;img src='myimage.jpg'&gt;")  )    
    // "<img src='myimage.jpg'>"
    
    console.log(  htmlDecode("<img src='dummy' onerror='alert(/xss/)'>")  )  
    // ""

    此函数保证不会作为副作用运行任何JavaScript代码。任何HTML标记都将被忽略,只返回文本内容。

    兼容性说明 DOMParser 至少需要Chrome 30、Firefox 12、Opera 17、Internet Explorer 10、Safari 7.1或Microsoft Edge。因此,所有没有支持的浏览器都已经过了它们的EOL期,到2017年为止,只有旧版的IE和Safari版本(通常这些版本的数量还不够多)。

        3
  •  291
  •   Mark Amery Harley Holcombe    8 年前

    &amp; 它自己?

    如果你只需要处理 & 然后你可以这样做:

    var decoded = encoded.replace(/&amp;/g, '&');
    

    var elem = document.createElement('textarea');
    elem.innerHTML = encoded;
    var decoded = elem.value;
    

    textarea 而不是 div

        4
  •  107
  •   Mark Amery Harley Holcombe    8 年前

    从JavaScript解释HTML(文本或其他)的一个更现代的选项是 DOMParser 原料药( see here in MDN ). 这允许您使用浏览器的本机HTML解析器将字符串转换为HTML文档。自2014年底以来,所有主流浏览器的新版本都支持它。

    如果我们只想解码一些文本内容,我们可以将其作为文档体中的唯一内容,解析文档,并提取其 .body.textContent

    var encodedStr = 'hello &amp; world';
    
    var parser = new DOMParser;
    var dom = parser.parseFromString(
        '<!doctype html><body>' + encodedStr,
        'text/html');
    var decodedString = dom.body.textContent;
    
    console.log(decodedString);

    我们可以看到 the draft specification for DOMParser JavaScript没有为已解析的文档启用,因此我们可以在不考虑安全性的情况下执行此文本转换。

    这个 parseFromString(str, type) 方法必须运行这些步骤,具体取决于 类型 :

    • "text/html"

      解析 str公司 带着一个 HTML parser ,并返回新创建的 Document .

      脚本标志必须设置为“禁用”。

      注意

      script 元素被标记为不可执行,并且 noscript

    这超出了这个问题的范围,但是 请注意 如果您将解析的DOM节点本身(不仅仅是它们的文本内容)移动到活动文档DOM中,那么它们的脚本可能会重新启用,并且可能存在安全问题。我还没有研究过,所以请谨慎行事。

        5
  •  48
  •   Community CDub    7 年前

    Matthias Bynens有一个图书馆: https://github.com/mathiasbynens/he

    例子:

    console.log(
        he.decode("J&#246;rg &amp J&#xFC;rgen rocked to &amp; fro ")
    );
    // Logs "Jörg & Jürgen rocked to & fro"
    

    textarea 中描述的黑客 this answer 对于一个几乎重复的问题,与已经提出的各种类似方法不同,我所知道的没有安全漏洞:

    function decodeEntities(encodedString) {
        var textArea = document.createElement('textarea');
        textArea.innerHTML = encodedString;
        return textArea.value;
    }
    
    console.log(decodeEntities('1 &amp; 2')); // '1 & 2'
    

    但是请注意安全问题,影响到与此类似的方法,我在链接答案中列出了这些问题!这种方法是一种黑客行为,将来可以修改 文本区域 (或者特定浏览器中的bug)可能会导致依赖它的代码某天突然出现XSS漏洞。

        6
  •  39
  •   Chris Fulstow    15 年前

    如果您使用的是jQuery:

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

    否则,请使用 Strictly Software's Encoder Object ,它有一个极好的 htmlDecode() 功能。

        7
  •  22
  •   WaiKit Kung    11 年前
    var htmlEnDeCode = (function() {
        var charToEntityRegex,
            entityToCharRegex,
            charToEntity,
            entityToChar;
    
        function resetCharacterEntities() {
            charToEntity = {};
            entityToChar = {};
            // add the default set
            addCharacterEntities({
                '&amp;'     :   '&',
                '&gt;'      :   '>',
                '&lt;'      :   '<',
                '&quot;'    :   '"',
                '&#39;'     :   "'"
            });
        }
    
        function addCharacterEntities(newEntities) {
            var charKeys = [],
                entityKeys = [],
                key, echar;
            for (key in newEntities) {
                echar = newEntities[key];
                entityToChar[key] = echar;
                charToEntity[echar] = key;
                charKeys.push(echar);
                entityKeys.push(key);
            }
            charToEntityRegex = new RegExp('(' + charKeys.join('|') + ')', 'g');
            entityToCharRegex = new RegExp('(' + entityKeys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');
        }
    
        function htmlEncode(value){
            var htmlEncodeReplaceFn = function(match, capture) {
                return charToEntity[capture];
            };
    
            return (!value) ? value : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn);
        }
    
        function htmlDecode(value) {
            var htmlDecodeReplaceFn = function(match, capture) {
                return (capture in entityToChar) ? entityToChar[capture] : String.fromCharCode(parseInt(capture.substr(2), 10));
            };
    
            return (!value) ? value : String(value).replace(entityToCharRegex, htmlDecodeReplaceFn);
        }
    
        resetCharacterEntities();
    
        return {
            htmlEncode: htmlEncode,
            htmlDecode: htmlDecode
        };
    })();
    

    这是来自ExtJS的源代码。

        8
  •  17
  •   laggingreflex    10 年前

    element.innerText 也能起作用。

        9
  •  17
  •   Ben White    7 年前

    诀窍是使用浏览器的力量来解码特殊的HTML字符,但不允许浏览器执行的结果,如果它是实际的HTML。。。此函数使用正则表达式来标识和替换编码的HTML字符,每次一个字符。

    function unescapeHtml(html) {
        var el = document.createElement('div');
        return html.replace(/\&[#0-9a-z]+;/gi, function (enc) {
            el.innerHTML = enc;
            return el.innerText
        });
    }
    
        10
  •  17
  •   I am L    7 年前

    可以使用Lodash unescape/escape函数 https://lodash.com/docs/4.17.5#unescape

    import unescape from 'lodash/unescape';
    
    const str = unescape('fred, barney, &amp; pebbles');
    

    'fred, barney, & pebbles'

        11
  •  14
  •   cslotty    7 年前

    如果你像我一样在找它的话-同时有一个很好而且安全的JQuery方法。

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

    您可以在控制台中键入:

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

    所以$.parseHTML(x)返回一个数组,如果文本中有HTML标记,则数组长度将大于1。

        12
  •  8
  •   Jason Williams    8 年前

    jQuery将为您编码和解码。但是,您需要使用textarea标记,而不是div。

    var str1 = 'One & two & three';
    var str2 = "One &amp; two &amp; three";
      
    $(document).ready(function() {
       $("#encoded").text(htmlEncode(str1)); 
       $("#decoded").text(htmlDecode(str2));
    });
    
    function htmlDecode(value) {
      return $("<textarea/>").html(value).text();
    }
    
    function htmlEncode(value) {
      return $('<textarea/>').text(value).html();
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    
    <div id="encoded"></div>
    <div id="decoded"></div>
        13
  •  6
  •   Community CDub    7 年前

    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

        14
  •  4
  •   Chris    8 年前

    首先创建一个 <span id="decodeIt" style="display:none;"></span> 在身体的某个地方

    接下来,将要解码为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
    
        15
  •  3
  •   kender    15 年前

    这不是对您的问题的直接回答,但是您的RPC返回一些结构(无论是XML还是JSON或其他什么)以及该结构中的图像数据(示例中的url)不是更好吗?

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

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

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

        16
  •  3
  •   ninhjs.dev    7 年前

    const htmlDecode = innerHTML => Object.assign(document.createElement('textarea'), {innerHTML}).value;
    
    console.log(htmlDecode('Complicated - Dimitri Vegas &amp; Like Mike'));
    
        17
  •  2
  •   nerijus    12 年前

    Chris的答案很好,很优雅,但如果价值太高,它就失败了 未定义 . 只要简单的改进就可以让它变得坚实:

    function htmlDecode(value) {
       return (typeof value === 'undefined') ? '' : $('<div/>').html(value).text();
    }
    
        18
  •  2
  •   Community CDub    7 年前

    一个javascript解决方案,可以捕获常见的解决方案:

    var map = {amp: '&', lt: '<', gt: '>', quot: '"', '#039': "'"}
    str = str.replace(/&([^;]+);/g, (m, c) => map[c])
    

    这与 https://stackoverflow.com/a/4835406/2738039

        19
  •  2
  •   buycanna.io    5 年前

    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);
                });
            }
        };
    

    全额学分: https://ourcodeworld.com/articles/read/188/encode-and-decode-html-entities-using-pure-javascript

        20
  •  2
  •   David Chopin    5 年前

    我疯了,把这个函数做得很漂亮,如果不是完全的话,也很详尽:

    function removeEncoding(string) {
        return string.replace(/&Agrave;/g, "À").replace(/&Aacute;/g, "Á").replace(/&Acirc;/g, "Â").replace(/&Atilde;/g, "Ã").replace(/&Auml;/g, "Ä").replace(/&Aring;/g, "Å").replace(/&agrave;/g, "à").replace(/&acirc;/g, "â").replace(/&atilde;/g, "ã").replace(/&auml;/g, "ä").replace(/&aring;/g, "å").replace(/&AElig;/g, "Æ").replace(/&aelig;/g, "æ").replace(/&szlig;/g, "ß").replace(/&Ccedil;/g, "Ç").replace(/&ccedil;/g, "ç").replace(/&Egrave;/g, "È").replace(/&Eacute;/g, "É").replace(/&Ecirc;/g, "Ê").replace(/&Euml;/g, "Ë").replace(/&egrave;/g, "è").replace(/&eacute;/g, "é").replace(/&ecirc;/g, "ê").replace(/&euml;/g, "ë").replace(/&#131;/g, "ƒ").replace(/&Igrave;/g, "Ì").replace(/&Iacute;/g, "Í").replace(/&Icirc;/g, "Î").replace(/&Iuml;/g, "Ï").replace(/&igrave;/g, "ì").replace(/&iacute;/g, "í").replace(/&icirc;/g, "î").replace(/&iuml;/g, "ï").replace(/&Ntilde;/g, "Ñ").replace(/&ntilde;/g, "ñ").replace(/&Ograve;/g, "Ò").replace(/&Oacute;/g, "Ó").replace(/&Ocirc;/g, "Ô").replace(/&Otilde;/g, "Õ").replace(/&Ouml;/g, "Ö").replace(/&ograve;/g, "ò").replace(/&oacute;/g, "ó").replace(/&ocirc;/g, "ô").replace(/&otilde;/g, "õ").replace(/&ouml;/g, "ö").replace(/&Oslash;/g, "Ø").replace(/&oslash;/g, "ø").replace(/&#140;/g, "Œ").replace(/&#156;/g, "œ").replace(/&#138;/g, "Š").replace(/&#154;/g, "š").replace(/&Ugrave;/g, "Ù").replace(/&Uacute;/g, "Ú").replace(/&Ucirc;/g, "Û").replace(/&Uuml;/g, "Ü").replace(/&ugrave;/g, "ù").replace(/&uacute;/g, "ú").replace(/&ucirc;/g, "û").replace(/&uuml;/g, "ü").replace(/&#181;/g, "µ").replace(/&#215;/g, "×").replace(/&Yacute;/g, "Ý").replace(/&#159;/g, "Ÿ").replace(/&yacute;/g, "ý").replace(/&yuml;/g, "ÿ").replace(/&#176;/g, "°").replace(/&#134;/g, "†").replace(/&#135;/g, "‡").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&#177;/g, "±").replace(/&#171;/g, "«").replace(/&#187;/g, "»").replace(/&#191;/g, "¿").replace(/&#161;/g, "¡").replace(/&#183;/g, "·").replace(/&#149;/g, "•").replace(/&#153;/g, "™").replace(/&copy;/g, "©").replace(/&reg;/g, "®").replace(/&#167;/g, "§").replace(/&#182;/g, "¶").replace(/&Alpha;/g, "Α").replace(/&Beta;/g, "Β").replace(/&Gamma;/g, "Γ").replace(/&Delta;/g, "Δ").replace(/&Epsilon;/g, "Ε").replace(/&Zeta;/g, "Ζ").replace(/&Eta;/g, "Η").replace(/&Theta;/g, "Θ").replace(/&Iota;/g, "Ι").replace(/&Kappa;/g, "Κ").replace(/&Lambda;/g, "Λ").replace(/&Mu;/g, "Μ").replace(/&Nu;/g, "Ν").replace(/&Xi;/g, "Ξ").replace(/&Omicron;/g, "Ο").replace(/&Pi;/g, "Π").replace(/&Rho;/g, "Ρ").replace(/&Sigma;/g, "Σ").replace(/&Tau;/g, "Τ").replace(/&Upsilon;/g, "Υ").replace(/&Phi;/g, "Φ").replace(/&Chi;/g, "Χ").replace(/&Psi;/g, "Ψ").replace(/&Omega;/g, "Ω").replace(/&alpha;/g, "α").replace(/&beta;/g, "β").replace(/&gamma;/g, "γ").replace(/&delta;/g, "δ").replace(/&epsilon;/g, "ε").replace(/&zeta;/g, "ζ").replace(/&eta;/g, "η").replace(/&theta;/g, "θ").replace(/&iota;/g, "ι").replace(/&kappa;/g, "κ").replace(/&lambda;/g, "λ").replace(/&mu;/g, "μ").replace(/&nu;/g, "ν").replace(/&xi;/g, "ξ").replace(/&omicron;/g, "ο").replace(/&piρ;/g, "ρ").replace(/&rho;/g, "ς").replace(/&sigmaf;/g, "ς").replace(/&sigma;/g, "σ").replace(/&tau;/g, "τ").replace(/&phi;/g, "φ").replace(/&chi;/g, "χ").replace(/&psi;/g, "ψ").replace(/&omega;/g, "ω").replace(/&bull;/g, "•").replace(/&hellip;/g, "…").replace(/&prime;/g, "′").replace(/&Prime;/g, "″").replace(/&oline;/g, "‾").replace(/&frasl;/g, "⁄").replace(/&weierp;/g, "℘").replace(/&image;/g, "ℑ").replace(/&real;/g, "ℜ").replace(/&trade;/g, "™").replace(/&alefsym;/g, "ℵ").replace(/&larr;/g, "←").replace(/&uarr;/g, "↑").replace(/&rarr;/g, "→").replace(/&darr;/g, "↓").replace(/&barr;/g, "↔").replace(/&crarr;/g, "↵").replace(/&lArr;/g, "⇐").replace(/&uArr;/g, "⇑").replace(/&rArr;/g, "⇒").replace(/&dArr;/g, "⇓").replace(/&hArr;/g, "⇔").replace(/&forall;/g, "∀").replace(/&part;/g, "∂").replace(/&exist;/g, "∃").replace(/&empty;/g, "∅").replace(/&nabla;/g, "∇").replace(/&isin;/g, "∈").replace(/&notin;/g, "∉").replace(/&ni;/g, "∋").replace(/&prod;/g, "∏").replace(/&sum;/g, "∑").replace(/&minus;/g, "−").replace(/&lowast;/g, "∗").replace(/&radic;/g, "√").replace(/&prop;/g, "∝").replace(/&infin;/g, "∞").replace(/&OEig;/g, "Œ").replace(/&oelig;/g, "œ").replace(/&Yuml;/g, "Ÿ").replace(/&spades;/g, "♠").replace(/&clubs;/g, "♣").replace(/&hearts;/g, "♥").replace(/&diams;/g, "♦").replace(/&thetasym;/g, "ϑ").replace(/&upsih;/g, "ϒ").replace(/&piv;/g, "ϖ").replace(/&Scaron;/g, "Š").replace(/&scaron;/g, "š").replace(/&ang;/g, "∠").replace(/&and;/g, "∧").replace(/&or;/g, "∨").replace(/&cap;/g, "∩").replace(/&cup;/g, "∪").replace(/&int;/g, "∫").replace(/&there4;/g, "∴").replace(/&sim;/g, "∼").replace(/&cong;/g, "≅").replace(/&asymp;/g, "≈").replace(/&ne;/g, "≠").replace(/&equiv;/g, "≡").replace(/&le;/g, "≤").replace(/&ge;/g, "≥").replace(/&sub;/g, "⊂").replace(/&sup;/g, "⊃").replace(/&nsub;/g, "⊄").replace(/&sube;/g, "⊆").replace(/&supe;/g, "⊇").replace(/&oplus;/g, "⊕").replace(/&otimes;/g, "⊗").replace(/&perp;/g, "⊥").replace(/&sdot;/g, "⋅").replace(/&lcell;/g, "⌈").replace(/&rcell;/g, "⌉").replace(/&lfloor;/g, "⌊").replace(/&rfloor;/g, "⌋").replace(/&lang;/g, "⟨").replace(/&rang;/g, "⟩").replace(/&loz;/g, "◊").replace(/&#039;/g, "'").replace(/&amp;/g, "&").replace(/&quot;/g, "\"");
    }
    

    像这样使用:

    let decodedText = removeEncoding("Ich hei&szlig;e David");
    console.log(decodedText);
    

    印刷品: Ich Heiße David

    顺便说一下,这花了一个半小时。

        21
  •  2
  •   Daniel    5 年前

    这是我迄今为止尝试过的最全面的解决方案:

    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]
            );
    };
    
        22
  •  2
  •   Andrew Hodgkinson    5 年前

    这个问题没有具体说明 x 但是,如果可以的话,防御恶意(或者来自我们自己的应用程序的意外)输入是有意义的。例如,假设 值为 &amp; <script>alert('hello');</script>

    var x    = "&amp; <script>alert('hello');</script>";
    var safe = $('<div />').html(x).text();
    
    // => "& alert('hello');"
    

    通过找到 https://gist.github.com/jmblog/3222899 . 我看不出有多少理由避免使用这个解决方案,因为它至少和某些替代方案一样短,甚至更短 防御XSS。

    (我最初将此作为评论发布,但现在将其作为答案添加,因为同一线程中的后续评论要求我这样做)。

        23
  •  1
  •   TheLethalCoder    6 年前

    我尝试了从JSON数组中删除&的所有操作。以上都不是例子,但是 https://stackoverflow.com/users/2030321/chris 给了我一个很好的解决方案,使我解决了我的问题。

    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],"&amp;", "&"));
    

    我喜欢它,因为它很简单,而且很有效,但不知道为什么它没有被广泛使用。搜索hi&low以找到简单的解决方案。 我继续寻求对语法的理解,如果使用它有任何风险的话。还没有找到任何东西。

        24
  •  1
  •   Łukasz K    4 年前

    要在JavaScript中取消显示HTML实体*,可以使用小型库 html-escaper : npm install html-escaper

    import {unescape} from 'html-escaper';
    
    unescape('escaped string');
    

    或者 unescape 函数来自 Lodash Underscore


    *)请注意,这些函数并不涵盖所有的HTML实体,而是只涵盖最常见的实体,即。 & , < > , ' , " he 图书馆。

        25
  •  0
  •   weiya ou    4 年前

    闭包可以避免创建不必要的对象。

    const decodingHandler = (() => {
      const element = document.createElement('div');
      return text => {
        element.innerHTML = text;
        return element.textContent;
      };
    })();
    

    const decodingHandler = (() => {
      const element = document.createElement('div');
      return text => ((element.innerHTML = text), element.textContent);
    })();
    
        26
  •  -1
  •   tmx976    7 年前

    我在我的项目中使用这个:灵感来自 other answers 但是如果有一个额外的安全参数,在处理修饰字符时可能会很有用

    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>';
    
        27
  •  -1
  •   EricP Vaibhav    7 年前

    其他答案都有问题。

    这个文档.createElement('div')方法(包括那些使用jQuery的方法)执行传递给它的任何javascript(安全问题)和DOMParser.parseFromString()方法修剪空白。下面是一个纯javascript解决方案,它没有任何问题:

    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('&lt;&amp;&nbsp;&gt;'); // 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.
    
        28
  •  -1
  •   jagjeet    5 年前
    var encodedStr = 'hello &amp; world';
    
    var parser = new DOMParser;
    var dom = parser.parseFromString(
        '<!doctype html><body>' + encodedStr,
        'text/html');
    var decodedString = dom.body.textContent;
    
    console.log(decodedString);
    
        29
  •  -2
  •   nand-63    4 年前

    function decodeHTMLContent(htmlText) {
      var txt = document.createElement("span");
      txt.innerHTML = htmlText;
      return txt.innerText;
    }
    
    var result = decodeHTMLContent('One &amp; two &amp; three');
    console.log(result);
        30
  •  -7
  •   Илья Зелень    6 年前

    有一种变体,80%的效率与最高层的答案相当。

    https://jsperf.com/decode-html12345678/1

    performance test

    console.log(decodeEntities('test: &gt'));
    
    function decodeEntities(str) {
      // this prevents any overhead from creating the object each time
      const el = decodeEntities.element || document.createElement('textarea')
    
      // strip script/html tags
      el.innerHTML = str
        .replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '')
        .replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
    
      return el.value;
    }

    如果你需要留下标签,那就把这两个去掉 .replace(...) 调用(如果不需要脚本,可以保留第一个调用)。