Unescape HTML entities in Javascript?

前端 未结 30 2908
野趣味
野趣味 2020-11-21 05:40

I have some Javascript code that communicates with an XML-RPC backend. The XML-RPC returns strings of the form:


相关标签:
30条回答
  • 2020-11-21 05:43

    EDIT: You should use the DOMParser API as Wladimir suggests, I edited my previous answer since the function posted introduced a security vulnerability.

    The following snippet is the old answer's code with a small modification: using a textarea instead of a div reduces the XSS vulnerability, but it is still problematic in IE9 and 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'>"
    

    Basically I create a DOM element programmatically, assign the encoded HTML to its innerHTML and retrieve the nodeValue from the text node created on the innerHTML insertion. Since it just creates an element but never adds it, no site HTML is modified.

    It will work cross-browser (including older browsers) and accept all the HTML Character Entities.

    EDIT: The old version of this code did not work on IE with blank inputs, as evidenced here on jsFiddle (view in IE). The version above works with all inputs.

    UPDATE: appears this doesn't work with large string, and it also introduces a security vulnerability, see comments.

    0 讨论(0)
  • 2020-11-21 05:43

    element.innerText also does the trick.

    0 讨论(0)
  • 2020-11-21 05:43

    Chris answer is nice & elegant but it fails if value is undefined. Just simple improvement makes it solid:

    function htmlDecode(value) {
       return (typeof value === 'undefined') ? '' : $('<div/>').html(value).text();
    }
    
    0 讨论(0)
  • 2020-11-21 05:44

    For one-line guys:

    const htmlDecode = innerHTML => Object.assign(document.createElement('textarea'), {innerHTML}).value;
    
    console.log(htmlDecode('Complicated - Dimitri Vegas &amp; Like Mike'));
    
    0 讨论(0)
  • 2020-11-21 05:45

    First create a <span id="decodeIt" style="display:none;"></span> somewhere in the body

    Next, assign the string to be decoded as innerHTML to this:

    document.getElementById("decodeIt").innerHTML=stringtodecode
    

    Finally,

    stringtodecode=document.getElementById("decodeIt").innerText
    

    Here is the overall code:

    var stringtodecode="<B>Hello</B> world<br>";
    document.getElementById("decodeIt").innerHTML=stringtodecode;
    stringtodecode=document.getElementById("decodeIt").innerText
    
    0 讨论(0)
  • 2020-11-21 05:46

    CMS' answer works fine, unless the HTML you want to unescape is very long, longer than 65536 chars. Because then in Chrome the inner HTML gets split into many child nodes, each one at most 65536 long, and you need to concatenate them. This function works also for very long strings:

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

    See this answer about innerHTML max length for more info: https://stackoverflow.com/a/27545633/694469

    0 讨论(0)
提交回复
热议问题