javascript - HTML-Entitätsdekodierung



html heading (12)

Diese Frage hat hier bereits eine Antwort:

Wie kodiere und dekodiere ich HTML-Entitäten mit JavaScript oder JQuery?

var varTitle = "Chris' corner";

Ich will es sein:

var varTitle = "Chris' corner";

Da @Robert K und @mattcasey beide einen guten Code haben, dachte ich, ich würde hier mit einer CoffeeScript-Version beitragen, für den Fall, dass irgendjemand in der Zukunft sie verwenden könnte:

    String::unescape = (strict = false) ->
      ###
      # Take escaped text, and return the unescaped version
      #
      # @param string str | String to be used
      # @param bool strict | Stict mode will remove all HTML
      #
      # Test it here:
      # https://jsfiddle.net/tigerhawkvok/t9pn1dn5/
      #
      # Code: https://gist.github.com/tigerhawkvok/285b8631ed6ebef4446d
      ###
      # Create a dummy element
      element = document.createElement("div")
      decodeHTMLEntities = (str) ->
        if str? and typeof str is "string"
          unless strict is true
            # escape HTML tags
            str = escape(str).replace(/%26/g,'&').replace(/%23/g,'#').replace(/%3B/g,';')
          else
            str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '')
            str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '')
          element.innerHTML = str
          if element.innerText
            # Do we support innerText?
            str = element.innerText
            element.innerText = ""
          else
            # Firefox
            str = element.textContent
            element.textContent = ""
        unescape(str)
      # Remove encoded or double-encoded tags
      fixHtmlEncodings = (string) ->
        string = string.replace(/\&amp;#/mg, '&#') # The rest, for double-encodings
        string = string.replace(/\&quot;/mg, '"')
        string = string.replace(/\&quote;/mg, '"')
        string = string.replace(/\&#95;/mg, '_')
        string = string.replace(/\&#39;/mg, "'")
        string = string.replace(/\&#34;/mg, '"')
        string = string.replace(/\&#62;/mg, '>')
        string = string.replace(/\&#60;/mg, '<')
        string
      # Run it
      tmp = fixHtmlEncodings(this)
      decodeHTMLEntities(tmp)

Siehe https://jsfiddle.net/tigerhawkvok/t9pn1dn5/7/ oder https://gist.github.com/tigerhawkvok/285b8631ed6ebef4446d (enthält kompiliertes JS und wird wahrscheinlich im Vergleich zu dieser Antwort aktualisiert)


Dies ist meine bevorzugte Art, HTML-Zeichen zu dekodieren. Der Vorteil der Verwendung dieses Codes besteht darin, dass Tags ebenfalls beibehalten werden.

function decodeHtml(html) {
    var txt = document.createElement("textarea");
    txt.innerHTML = html;
    return txt.value;
}

Beispiel: http://jsfiddle.net/k65s3/

Eingang:

Entity:&nbsp;Bad attempt at XSS:<script>alert('new\nline?')</script><br>

Ausgabe:

Entity: Bad attempt at XSS:<script>alert('new\nline?')</script><br>

Eine funktionellere Herangehensweise an @William Lahtis Antwort:

var entities = {
  'amp': '&',
  'apos': '\'',
  '#x27': '\'',
  '#x2F': '/',
  '#39': '\'',
  '#47': '/',
  'lt': '<',
  'gt': '>',
  'nbsp': ' ',
  'quot': '"'
}

function decodeHTMLEntities (text) {
  return text.replace(/&([^;]+);/gm, function (match, entity) {
    return entities[entity] || match
  })
}


Hier ist eine andere Version:

function convertHTMLEntity(text){
    const span = document.createElement('span');

    return text
    .replace(/&[#A-Za-z0-9]+;/gi, (entity,position,text)=> {
        span.innerHTML = entity;
        return span.innerText;
    });
}

console.log(convertHTMLEntity('Large &lt; &#163; 500'));


Hier ist eine schnelle Methode, die kein div zu erstellen braucht, und entschlüsselt die "am häufigsten" HTML-Zeichen mit Escapezeichen:

function decodeHTMLEntities(text) {
    var entities = [
        ['amp', '&'],
        ['apos', '\''],
        ['#x27', '\''],
        ['#x2F', '/'],
        ['#39', '\''],
        ['#47', '/'],
        ['lt', '<'],
        ['gt', '>'],
        ['nbsp', ' '],
        ['quot', '"']
    ];

    for (var i = 0, max = entities.length; i < max; ++i) 
        text = text.replace(new RegExp('&'+entities[i][0]+';', 'g'), entities[i][1]);

    return text;
}

Ich empfehle, den jQuery-Code zu verwenden, der als Antwort akzeptiert wurde. Während die Zeichenfolge nicht zum Dekodieren in die Seite eingefügt wird, werden jedoch Dinge wie Skripts und HTML-Elemente erstellt. Das ist viel mehr Code als wir brauchen. Stattdessen schlage ich vor, eine sicherere, optimierte Funktion zu verwenden.

var decodeEntities = (function() {
  // this prevents any overhead from creating the object each time
  var element = document.createElement('div');

  function decodeHTMLEntities (str) {
    if(str && typeof str === 'string') {
      // strip script/html tags
      str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
      str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
      element.innerHTML = str;
      str = element.textContent;
      element.textContent = '';
    }

    return str;
  }

  return decodeHTMLEntities;
})();

http://jsfiddle.net/LYteC/4/

Um diese Funktion zu verwenden, rufen decodeEntities("&amp;") einfach decodeEntities("&amp;") und es werden die gleichen zugrunde liegenden Techniken wie in der jQuery-Version verwendet - jedoch ohne den Overhead von jQuery und nach der Bereinigung der HTML-Tags in der Eingabe. Siehe Mike Samuels Kommentar zu der akzeptierten Antwort zum Ausfiltern von HTML-Tags.

Diese Funktion kann leicht als jQuery-Plugin verwendet werden, indem Sie die folgende Zeile in Ihrem Projekt hinzufügen.

jQuery.decodeEntities = decodeEntities;

Ich weiß, dass ich ein wenig zu spät zum Spiel bin, aber ich dachte, ich könnte das folgende Snippet als Beispiel dafür liefern, wie ich HTML-Entitäten mit jQuery decodiere:

var varTitleE = "Chris&apos; corner";
var varTitleD = $("<div/>").html(varTitleE).text();

console.log(varTitleE + " vs. " + varTitleD);​​​​​​​​​​​

Vergiss nicht, deinen Inspector / Firebug anzuwerfen, um die Konsolenergebnisse zu sehen - oder ersetze einfach console.log (...) w / alert (...)

Das heißt, was meine Konsole über den Google Chrome-Inspektor liest:

Chris&apos; corner vs. Chris' corner

Inspiriert von der Lösung von Robert K. streift html Tags und verhindert das Ausführen von Skripten und Eventhandlern wie: <img src=fake onerror="prompt(1)"> Getestet am neuesten Chrome, FF, IE (sollte von IE9 funktionieren, aber nicht getestet ).

var decodeEntities = (function () {
        //create a new html document (doesn't execute script tags in child elements)
        var doc = document.implementation.createHTMLDocument("");
        var element = doc.createElement('div');

        function getText(str) {
            element.innerHTML = str;
            str = element.textContent;
            element.textContent = '';
            return str;
        }

        function decodeHTMLEntities(str) {
            if (str && typeof str === 'string') {
                var x = getText(str);
                while (str !== x) {
                    str = x;
                    x = getText(x);
                }
                return x;
            }
        }
        return decodeHTMLEntities;
    })();

Rufen Sie einfach an:

decodeEntities('<img src=fake onerror="prompt(1)">');
decodeEntities("<script>alert('aaa!')</script>");


Um noch eine weitere "von Robert K inspirierte" Liste hinzuzufügen, hier ist eine weitere sichere Version, die HTML-Tags nicht entfernt . Anstatt die gesamte Zeichenfolge durch den HTML-Parser zu führen, werden nur die Entitäten abgerufen und konvertiert.

var decodeEntities = (function() {
    // this prevents any overhead from creating the object each time
    var element = document.createElement('div');

    // regular expression matching HTML entities
    var entity = /&(?:#x[a-f0-9]+|#[0-9]+|[a-z0-9]+);?/ig;

    return function decodeHTMLEntities(str) {
        // find and replace all the html entities
        str = str.replace(entity, function(m) {
            element.innerHTML = m;
            return element.textContent;
        });

        // reset the value
        element.textContent = '';

        return str;
    }
})();

Wie Robert K sagte, benutze jQuery.html (). Text () nicht, um Html-Entities zu dekodieren, da es unsicher ist, da Benutzereingaben niemals Zugriff auf das DOM haben sollten. Lesen Sie über XSS warum dies unsicher ist.

Versuchen Sie stattdessen die Underscore.js Dienstprogramm-Gürtel-Bibliothek, die mit unescape und unescape Methoden unescape wird:

escape

Es wird eine Zeichenfolge zum Einfügen in HTML entfernt, wobei ' Zeichen & , < , > , " , ` und ' .

_.escape('Curly, Larry & Moe');
=> "Curly, Larry &amp; Moe"

unescape

Das Gegenteil von Escape, ersetzt &amp; , &lt; , &gt; &quot; , &#96; und &#x27; mit ihren unausgesprochenen Gegenstücken.

_.unescape('Curly, Larry &amp; Moe');
=> "Curly, Larry & Moe"

Um die Decodierung weiterer Zeichen zu unterstützen, kopieren Sie unescape Methode Underscore unescape und fügen Sie weitere Zeichen zur Karte hinzu.





html