HTML-Zeichenfolgen mit jQuery maskieren

609

Kennt jemand eine einfache Möglichkeit, HTML aus Zeichenfolgen in jQuery zu entfernen ? Ich muss in der Lage sein, eine beliebige Zeichenfolge zu übergeben und sie für die Anzeige auf einer HTML-Seite ordnungsgemäß maskieren zu lassen (um JavaScript / HTML-Injection-Angriffe zu verhindern). Ich bin sicher, dass es möglich ist, jQuery zu erweitern, um dies zu tun, aber ich weiß im Moment nicht genug über das Framework, um dies zu erreichen.

Seite
quelle
Siehe auch perf: jsperf.com/…
Christophe Roussy

Antworten:

445

Da Sie jQuery verwenden , können Sie einfach die textEigenschaft des Elements festlegen :

// before:
// <div class="someClass">text</div>
var someHtmlString = "<script>alert('hi!');</script>";

// set a DIV's text:
$("div.someClass").text(someHtmlString);
// after: 
// <div class="someClass">&lt;script&gt;alert('hi!');&lt;/script&gt;</div>

// get the text in a string:
var escaped = $("<div>").text(someHtmlString).html();
// value: 
// &lt;script&gt;alert('hi!');&lt;/script&gt;
Travis
quelle
57
Sie haben den Punkt verpasst, an dem Sie auf $ ("div.someClass"). Html () zugreifen müssen, um die maskierte Version herauszubekommen.
Morten Christiansen
16
Dies ist nicht browserübergreifend sicher, wenn Ihre Zeichenfolge Leerzeichen und \ n \ r \ t Zeichen enthält
nivcaner
20
@travis Dies ist auf der jQuery-Website dokumentiert: "Aufgrund von Abweichungen in den HTML-Parsern in verschiedenen Browsern kann der zurückgegebene Text in Zeilenumbrüchen und anderen Leerzeichen variieren." api.jquery.com/text
geofflee
3
@mklement Wenn Sie diese Lösung bereits verwenden, werden Sie keine Probleme damit haben, wie folgt : $(element2).attr("some-attr", $(element1).html());Siehe dieses Beispiel: jsbin.com/atibig/1/edit
travis
16
Dies entgeht NICHT Anführungszeichen und doppelten Anführungszeichen, was schlecht ist! wonko.com/post/html-escaping
Lior
601

Es gibt auch die Lösung von mustache.js

var entityMap = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#39;',
  '/': '&#x2F;',
  '`': '&#x60;',
  '=': '&#x3D;'
};

function escapeHtml (string) {
  return String(string).replace(/[&<>"'`=\/]/g, function (s) {
    return entityMap[s];
  });
}
Tom Gruner
quelle
7
Beachten Sie, dass seltsamerweise 'eine Entität mit einem Dezimalformat zugeordnet wird , während /das Hex- Format verwendet wird.
mklement0
43
Dies sollte die akzeptierte Antwort sein - es ist einfach, effizient, erfordert keine Abhängigkeiten und macht genau das, was beabsichtigt ist, ohne obskure Hacks.
Lorefnon
6
was ist die Anleitung zum Konvertieren \nzu <br>?
Amwinter
2
Hier ist ein aktualisierter Link zur Quelle: github.com/janl/mustache.js/blob/…
mjackson
8
@amwinter, ich habe das Skript oben um "\ n" erweitert: '<br>' zur Entitätszuordnung und den regulären Ausdruck auf / [& <> "'\ /] | [\ n] / g
walv
182
$('<div/>').text('This is fun & stuff').html(); // "This is fun &amp; stuff"

Quelle: http://debuggable.com/posts/encode-html-entities-with-jquery:480f4dd6-13cc-4ce9-8071-4710cbdd56cb

Henrik N.
quelle
11
Wie in der obigen Antwort erwähnt, kann bei dieser Lösung nicht garantiert werden, dass Leerzeichen erhalten bleiben.
Geofflee
47
Es ist zu beachten, dass dies nichts tut, um einfachen oder doppelten Anführungszeichen zu entgehen. Wenn Sie planen, den Wert in ein HTML-Attribut einzufügen, kann dies ein Problem sein.
Kip
6
@Kip: @travis hat festgestellt, dass die attr()Methode von jQuery (ab mindestens 1.8.3) eine eigene Codierung ausführt, sodass nicht codierte Zeichenfolgen direkt übergeben werden können . zB:$('<div/>').attr('test-attr', '\'Tis "fun" & stuff')[0].outerHTML
mklement0
1
@ Tarekahf Das ist seltsam. Welche Version von jQuery verwenden Sie? Funktioniert der Beispielcode, wenn Sie ihn wörtlich kopieren und einfügen? Funktioniert gut mit der neuesten jQuery (3.1.0) hier: jsbin.com/fazimigayo/1/edit?html,js,console,output (und es sollte auch auf allen früheren Versionen funktionieren)
Henrik N
1
@tarekahf $('<div/>')erstellt ein neues divElement, das nicht an das DOM angehängt ist. Es werden also keine vorhandenen Elemente geändert. Es ist ein bisschen verwirrend, wie jQuery dieselbe $()Funktion verwendet, um Elemente ( $('div')) zu finden und zu erstellen, und für ein paar weitere Dinge außer… :)
Henrik N
61

Wenn Sie sich für HTML entscheiden, gibt es nur drei, von denen ich mir vorstellen kann, dass sie wirklich notwendig wären:

html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");

Je nach Anwendungsfall, können Sie auch Dinge tun müssen , wie "zu &quot;. Wenn die Liste groß genug wäre, würde ich einfach ein Array verwenden:

var escaped = html;
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]
for(var item in findReplace)
    escaped = escaped.replace(findReplace[item][0], findReplace[item][1]);

encodeURIComponent() wird nur für URLs maskiert, nicht für HTML.

tghw
quelle
13
Dieser reguläre Ausdruck führt zu seltsamen Ergebnissen, wenn der betreffende HTML-Code bereits Entitäten entkommen ist. Wenn Sie beispielsweise "Tom & amp; Jerry" entkommen, wird "Tom & amp; Jerry"
Ryan
12
Bitte verwenden Sie, um vor Ort varzu deklarieren item; Verwenden Sie auf keinen Fall eine for … inSchleife, wenn Sie ein Array durchlaufen! Verwenden Sie forstattdessen eine normale Schleife. Oh, und das ist es encodeURIComponentnicht escapeURIComponent.
Marcel Korpel
3
Wenn Sie mit Tag-Attributen arbeiten, müssen Sie auch Anführungszeichen und / oder doppelte Anführungszeichen umgehen. Die PHP-Dokumentation für htmlspecialchars enthält eine nützliche Liste der durchgeführten Konvertierungen. php.net/htmlspecialchars
Geofflee
4
Nur eine nette Erinnerung für neue Leute, verwenden Sie dies nicht, wenn Sie beabsichtigen, irgendwo auf Ihrer Website nicht-englische Zeichen zu haben ... Offensichtlich ist dies aufgrund von Zeichen mit Akzenten wie 'é' nicht möglich : &eacute; Hier ist eine Liste von HTML-Entitäten als Referenz: w3schools.com/tags/ref_entities.asp
LoganWolfer
11
@Ryan: Es ist zwar erwähnenswert, dass diese Lösung bereits codierte Zeichenfolgen nicht korrekt verarbeitet, aber es ist auch nichts wert, was für die meisten - möglicherweise alle - Lösungen auf dieser Seite gilt.
mklement0
37

Einfach genug, um Unterstrich zu verwenden:

_.escape(string) 

Unterstrich ist eine Dienstprogrammbibliothek, die viele Funktionen bietet, die native js nicht bieten. Es gibt auch lodash, das die gleiche API wie der Unterstrich hat, aber umgeschrieben wurde, um leistungsfähiger zu sein.

chovy
quelle
36

Ich habe eine winzige kleine Funktion geschrieben, die dies tut. Es entgeht nur ", &, <und >(aber in der Regel das ist alles , was Sie brauchen sowieso). Es ist etwas eleganter als die zuvor vorgeschlagenen Lösungen, da nur eine .replace() für die gesamte Konvertierung verwendet wird. ( BEARBEITEN 2: Reduzierte Codekomplexität, wodurch die Funktion noch kleiner und übersichtlicher wird. Wenn Sie neugierig auf den Originalcode sind, lesen Sie das Ende dieser Antwort.)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&<>]/g, function (a) {
        return { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' }[a];
    });
}

Dies ist einfaches Javascript, es wird keine jQuery verwendet.

Flucht /und 'auch

Bearbeiten Sie als Antwort auf den Kommentar von mklement .

Die obige Funktion kann leicht um ein beliebiges Zeichen erweitert werden. Um weitere Zeichen anzugeben, die maskiert werden sollen, fügen Sie sie einfach sowohl in die Zeichenklasse im regulären Ausdruck (dh innerhalb des /[...]/g) als auch als Eintrag im chrObjekt ein. ( EDIT 2: In gleicher Weise wurde auch diese Funktion verkürzt.)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&'\/<>]/g, function (a) {
        return {
            '"': '&quot;', '&': '&amp;', "'": '&#39;',
            '/': '&#47;',  '<': '&lt;',  '>': '&gt;'
        }[a];
    });
}

Beachten Sie die obige Verwendung von &#39;für Apostroph (die symbolische Entität wurde &apos;möglicherweise stattdessen verwendet - sie ist in XML definiert, wurde jedoch ursprünglich nicht in die HTML-Spezifikation aufgenommen und wird daher möglicherweise nicht von allen Browsern unterstützt. Siehe: Wikipedia-Artikel zu HTML-Zeichencodierungen ). Ich erinnere mich auch daran, dass ich irgendwo gelesen habe, dass die Verwendung von Dezimalstellen stärker unterstützt wird als die Verwendung von Hexadezimal, aber ich kann die Quelle dafür derzeit nicht finden. (Und es kann nicht viele Browser geben, die die hexadezimalen Entitäten nicht unterstützen.)

Hinweis: Das Hinzufügen /und 'zur Liste der maskierten Zeichen ist nicht allzu nützlich, da sie in HTML keine besondere Bedeutung haben und nicht maskiert werden müssen.

Ursprüngliche escapeHtmlFunktion

BEARBEITEN 2: Die ursprüngliche Funktion verwendete eine Variable ( chr), um das für den .replace()Rückruf benötigte Objekt zu speichern . Diese Variable benötigte auch eine zusätzliche anonyme Funktion, um sie zu erweitern, wodurch die Funktion (unnötig) etwas größer und komplexer wurde.

var escapeHtml = (function () {
    'use strict';
    var chr = { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };
    return function (text) {
        return text.replace(/[\"&<>]/g, function (a) { return chr[a]; });
    };
}());

Ich habe nicht getestet, welche der beiden Versionen schneller sind. Wenn Sie dies tun, können Sie hier Informationen und Links dazu hinzufügen.

zrajm
quelle
Vielen Dank, dass Sie sich die Zeit genommen haben, @Zrajm. Guter Punkt, um nicht entkommen zu müssen; Irgendeine Idee warum beides mustache.jsund es underscore.jstun? Apropos letzteres: Es erkennt nur die numerischen Entitäten (die 'und /'darstellen) in hexadezimaler Großbuchstabe , wenn sie nicht entkommen. So kam Text herein mustache.js- der seltsamerweise eine Mischung aus Hex verwendet. und Dezimalformate - würden nicht korrekt entkoppelt underscore.js. Ich frage mich, wie andere populäre Bibliotheken damit umgehen.
mklement0
1
Die untere Gehäuse hex Form ist die Form unterstützt, so dass ist (wahrscheinlich) die Form , dass die Bibliotheken umwandeln sollten zu . (Natürlich sollten beide Formulare beim Konvertieren von' funktionieren .) - Apostrophe haben eine reservierte Funktion in XML (und damit XHTML, wie ich mir vorstellen kann?), Aus diesem Grund haben XML (aber nicht HTML) die benannte Entität &apos;. Genau warum oder auf welche Weise es "reserviert" ist, weiß ich nicht. - Schrägstriche sind in URLs speziell, aber das bedeutet nicht eigentlich sie für die Aufnahme rechtfertigen HTML entkommen (als URL - Codierung etwas ganz anderes ist).
Zrajm
Betreff &apos;: richtig: sichere Verwendung nur in XHTML ; direkt aus dem Mund der Crowd-Quelle - Hervorhebung von mir: "(...) von einem konformen HTML- Prozessor gelesen , (...) die Verwendung von & apos; oder benutzerdefinierten Entitätsreferenzen wird möglicherweise nicht unterstützt (...)" - in der Praxis : Moderne Browser unterstützen es sogar in HTML . Siehe Fall in Hex-Nummern. (gleiche Quelle; Hervorhebung von mir): "Das x muss in XML-Dokumenten in Kleinbuchstaben geschrieben sein. […] Das hhhh kann Groß- und Kleinbuchstaben mischen, obwohl Großbuchstaben der übliche Stil sind ." Wir müssen uns fragen, wer beschlossen hat, Schrägstriche zu codieren. Vielleicht wirklich nur eine Verwechslung zwischen URI und HTML-Codierung?
mklement0
2
Letzte Gedanken: Es scheint, dass /keine Codierung erforderlich ist, aber die Codierung 'scheint dennoch nützlich zu sein, um den Fall sicher zu behandeln, in dem eine codierte Zeichenfolge als Attributwert in einfachen Anführungszeichen verwendet wird .
mklement0
Beide sind langsam. Die mit einem zweistelligen Abstand schnellste Lösung ist eine Reihe von Ersetzungen, bei denen Zeichenfolgen anstelle von Funktionen übergeben werden.
Adam Leggett
34

Mir ist klar, wie spät ich zu dieser Party komme, aber ich habe eine sehr einfache Lösung, für die jQuery nicht erforderlich ist.

escaped = new Option(unescaped).innerHTML;

Bearbeiten: Dies entgeht keinen Anführungszeichen. Der einzige Fall, in dem Anführungszeichen maskiert werden müssten, besteht darin, dass der Inhalt in ein Attribut innerhalb einer HTML-Zeichenfolge eingefügt wird. Es fällt mir schwer, mir einen Fall vorzustellen, in dem dies ein gutes Design wäre.

Bearbeiten 3: Für die schnellste Lösung überprüfen Sie die Antwort oben von Saram. Dieser ist der kürzeste.

Adam Leggett
quelle
Dies ändert keine Anführungszeichen - zumindest jetzt in Firefox 52.
Getsetbro
1
Das Escaping von Anführungszeichen ist nur in Attributen funktional relevant. Da wir entkommen <und >es keinen Vorteil hat, auch den Anführungszeichen zu entkommen, es sei denn, die Absicht des generierten Inhalts besteht darin, in ein Attribut zu gehen.
Adam Leggett
31

Hier ist eine saubere, klare JavaScript-Funktion. Es wird Text wie "einige <viele" in "einige & lt; viele" maskieren.

function escapeHtmlEntities (str) {
  if (typeof jQuery !== 'undefined') {
    // Create an empty div to use as a container,
    // then put the raw text in and get the HTML
    // equivalent out.
    return jQuery('<div/>').text(str).html();
  }

  // No jQuery, so use string replace.
  return str
    .replace(/&/g, '&amp;')
    .replace(/>/g, '&gt;')
    .replace(/</g, '&lt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&apos;');
}
unerschrocken
quelle
28

Nach letzten Tests kann ich empfehlen schnellste und vollständig Cross - Browser - kompatibel nativen javaScript (DOM) Lösung:

function HTMLescape(html){
    return document.createElement('div')
        .appendChild(document.createTextNode(html))
        .parentNode
        .innerHTML
}

Wenn Sie es viele Male wiederholen, können Sie es mit einmal vorbereiteten Variablen tun:

//prepare variables
var DOMtext = document.createTextNode("test");
var DOMnative = document.createElement("span");
DOMnative.appendChild(DOMtext);

//main work for each case
function HTMLescape(html){
  DOMtext.nodeValue = html;
  return DOMnative.innerHTML
}

Sehen Sie sich meine Endleistung Vergleich ( Stack Frage ).

Saram
quelle
2
Müssen zwei Knoten verwendet werden? Wie wäre es mit nur einem:var p = document.createElement('p'); p.textContent = html; return p.innerHTML;
Dan Dascalescu
2
@DanDascalescu: Laut MDN wird die textContentFunktion nur von Chrome 1+, Firefox 2, IE9, Opera 9.64 und Safari 3 unterstützt (die beiden letzteren haben "möglicherweise früher" kommentiert). Dies würde die Behauptung der OPs "vollständig browserübergreifend kompatibel" brechen.
zb226
p.innerText = html; return p.innerHTML
Bekim Bacaj
24

Versuchen Sie Underscore.string lib, es funktioniert mit jQuery.

_.str.escapeHTML('<div>Blah blah blah</div>')

Ausgabe:

'&lt;div&gt;Blah blah blah&lt;/div&gt;'
Nikita Koksharov
quelle
20
Die Haupt-Unterstrichbibliothek verfügt jetzt über eine _.escape()Dienstprogrammfunktion.
Codeape
15

Ich habe das Beispiel mustache.js erweitert und die escapeHTML()Methode zum Zeichenfolgenobjekt hinzugefügt .

var __entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#39;',
    "/": '&#x2F;'
};

String.prototype.escapeHTML = function() {
    return String(this).replace(/[&<>"'\/]/g, function (s) {
        return __entityMap[s];
    });
}

Auf diese Weise ist es recht einfach zu bedienen "Some <text>, more Text&Text".escapeHTML()

Jeena
quelle
Nützlich, aber ich bin auch __entityMapin den Funktionsbereich vor Ort übergegangen. Und wickelte all dies inif (typeof String.prototype.escapeHTML !== 'function'){...}
FlameStorm
15

escape()und unescape()sollen Zeichenfolgen für URLs und nicht für HTML codieren / decodieren.

Eigentlich verwende ich das folgende Snippet, um den Trick auszuführen, für den kein Framework erforderlich ist:

var escapedHtml = html.replace(/&/g, '&amp;')
                      .replace(/>/g, '&gt;')
                      .replace(/</g, '&lt;')
                      .replace(/"/g, '&quot;')
                      .replace(/'/g, '&apos;');
NicolasBernier
quelle
Wenn du "s haben willst, musst du mindestens 'und `` zum Kampf hinzufügen . Diese werden nur für String-Tag-Daten in Elementen in HTML benötigt. Für HTML-Daten selbst (außerhalb von Tags) sind nur die ersten 3 erforderlich.
Marius
10

Wenn Sie underscore.js haben, verwenden Sie _.escape(effizienter als die oben beschriebene jQuery-Methode):

_.escape('Curly, Larry & Moe'); // returns: Curly, Larry &amp; Moe
Ronnbot
quelle
5

Wenn Sie die Regex-Route wählen, ist im obigen Beispiel von tghw ein Fehler aufgetreten.

<!-- WON'T WORK -  item[0] is an index, not an item -->

var escaped = html; 
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g,"&gt;"], [/"/g,
"&quot;"]]

for(var item in findReplace) {
     escaped = escaped.replace(item[0], item[1]);   
}


<!-- WORKS - findReplace[item[]] correctly references contents -->

var escaped = html;
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]

for(var item in findReplace) {
     escaped = escaped.replace(findReplace[item[0]], findReplace[item[1]]);
}
Wayne
quelle
2
Ich glaube, es sollte sein für (var item in findReplace) {entkommen = entkommen.replace (findReplace [item] [0], findReplace [item] [1]); }
Chris Stephens
5

Dies ist ein schönes sicheres Beispiel ...

function escapeHtml(str) {
    if (typeof(str) == "string"){
        try{
            var newStr = "";
            var nextCode = 0;
            for (var i = 0;i < str.length;i++){
                nextCode = str.charCodeAt(i);
                if (nextCode > 0 && nextCode < 128){
                    newStr += "&#"+nextCode+";";
                }
                else{
                    newStr += "?";
                }
             }
             return newStr;
        }
        catch(err){
        }
    }
    else{
        return str;
    }
}
amrp
quelle
4
Welche Arten von Ausnahmen unterdrücken Sie dort?
Stefan Majewsky
3

Sie können es leicht mit Vanille js tun.

Fügen Sie dem Dokument einfach einen Textknoten hinzu. Es wird vom Browser maskiert.

var escaped = document.createTextNode("<HTML TO/ESCAPE/>")
document.getElementById("[PARENT_NODE]").appendChild(escaped)
raam86
quelle
2
(function(undefined){
    var charsToReplace = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;'
    };

    var replaceReg = new RegExp("[" + Object.keys(charsToReplace).join("") + "]", "g");
    var replaceFn = function(tag){ return charsToReplace[tag] || tag; };

    var replaceRegF = function(replaceMap) {
        return (new RegExp("[" + Object.keys(charsToReplace).concat(Object.keys(replaceMap)).join("") + "]", "gi"));
    };
    var replaceFnF = function(replaceMap) {
        return function(tag){ return replaceMap[tag] || charsToReplace[tag] || tag; };
    };

    String.prototype.htmlEscape = function(replaceMap) {
        if (replaceMap === undefined) return this.replace(replaceReg, replaceFn);
        return this.replace(replaceRegF(replaceMap), replaceFnF(replaceMap));
    };
})();

Keine globalen Variablen, etwas Speicheroptimierung. Verwendungszweck:

"some<tag>and&symbol©".htmlEscape({'©': '&copy;'})

Ergebnis ist:

"some&lt;tag&gt;and&amp;symbol&copy;"
Gheljenor
quelle
2

2 einfache Methoden, die KEINE JQUERY erfordern ...

Sie können alle Zeichen in Ihrer Zeichenfolge folgendermaßen codieren :

function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}

Oder einfach nur die Hauptfiguren Ziel zu kümmern &, Zeilenumbrüche <, >, "und 'wie:

function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}

var myString='Encode HTML entities!\n"Safe" escape <script></'+'script> & other tags!';

test.value=encode(myString);

testing.innerHTML=encode(myString);

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
<p><b>What JavaScript Generated:</b></p>

<textarea id=test rows="3" cols="55"></textarea>

<p><b>What It Renders Too In HTML:</b></p>

<div id="testing">www.WHAK.com</div>

Dave Brown
quelle
2

Beispiel für einfaches JavaScript-Escape:

function escapeHtml(text) {
    var div = document.createElement('div');
    div.innerText = text;
    return div.innerHTML;
}

escapeHtml("<script>alert('hi!');</script>")
// "&lt;script&gt;alert('hi!');&lt;/script&gt;"
Andrew Luca
quelle
3
Von Nur-Code-Antworten wird abgeraten, da sie nicht erklären, wie sie das Problem lösen. Bitte aktualisieren Sie Ihre Antwort, um zu erklären, wie sich dies gegenüber den anderen akzeptierten und positiv bewerteten Antworten verbessert, die diese Frage bereits hat. Außerdem ist diese Frage 9 Jahre alt. Ihre Bemühungen würden von Benutzern, die kürzlich unbeantwortete Fragen haben, mehr geschätzt. Bitte überprüfen Sie, wie ich eine gute Antwort schreibe .
FluffyKitten
1
@FluffyKitten hier ist ein sehr schön geschriebener Blog-Beitrag über die Vor- und Nachteile einer solchen Funktion, der ausführlich alles erklärt, was Sie wissen möchten
db306
@ db306 Die Antwort wurde als minderwertig gekennzeichnet, da die Nur-Code-Antwort nicht den Richtlinien für den Stapelüberlauf entspricht - siehe So schreiben Sie eine gute Antwort . Mein Kommentar wurde während des Überprüfungsprozesses hinzugefügt, um zu erklären, was zur Verbesserung erforderlich ist, dh die Antwort muss aktualisiert werden, um zu erklären, was der Code tut und wie er die vorhandenen Antworten verbessert. Die Upvotes stammen von anderen Rezensenten, um dies zu bestätigen. Das Hinzufügen eines externen Links zu den Kommentaren entspricht immer noch nicht den SO-Richtlinien. Stattdessen muss Andrew die relevanten Informationen direkt in seine Antwort aufnehmen.
FluffyKitten
Beachten Sie, dass brandonmintern DOT com abgelaufen ist und jetzt geparkt ist. Die neue shebang-Adresse lautet shebang.mintern.net/foolproof-html-escaping-in-javascript/.
Brandon
0
function htmlEscape(str) {
    var stringval="";
    $.each(str, function (i, element) {
        alert(element);
        stringval += element
            .replace(/&/g, '&amp;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(' ', '-')
            .replace('?', '-')
            .replace(':', '-')
            .replace('|', '-')
            .replace('.', '-');
    });
    alert(stringval);
    return String(stringval);
}
Katharapu Ramana
quelle
0
function htmlDecode(t){
   if (t) return $('<div />').html(t).text();
}

klappt wunderbar

d -_- b
quelle
Text entfernt HTML-Tags, aber $ ('<div />'). html (t) .html (); Werke
Bass Jobsen
0

Diese Antwort enthält die Methoden jQuery und normale JS, ist jedoch ohne Verwendung des DOM am kürzesten:

unescape(escape("It's > 20% less complicated this way."))

Escapezeichenfolge: It%27s%20%3E%2020%25%20less%20complicated%20this%20way.

Wenn Sie die entkommenen Leerzeichen stören, versuchen Sie:

unescape(escape("It's > 20% less complicated this way.").replace(/%20/g, " "))

Escapezeichenfolge: It%27s %3E 20%25 less complicated this way.

Leider war die escape()Funktion in JavaScript Version 1.5 veraltet . encodeURI()oder encodeURIComponent()sind Alternativen, aber sie ignorieren ', so dass die letzte Codezeile in folgende umgewandelt wird:

decodeURI(encodeURI("It's > 20% less complicated this way.").replace(/%20/g, " ").replace("'", '%27'))

Alle gängigen Browser unterstützen weiterhin den Funktionscode, und angesichts der Anzahl der alten Websites bezweifle ich, dass sich dies bald ändern wird.

Cees Timmerman
quelle
Dies ist für die URL-Codierung. Die Frage betraf das Entweichen von HTML, was sehr unterschiedlich ist.
Thelem
@thelem, nicht wenn die Zeichenfolgen in in HTML eingebettete JavaScript-Arrays eingebettet sind, aber ich stimme zu, dass es sich um einfaches HTML-Escape handelte, damit es sofort als Text angezeigt werden kann.
Cees Timmerman
0

ES6 ein Liner für die Lösung von mustache.js

const escapeHTML = str => (str+'').replace(/[&<>"'`=\/]/g, s => ({'&': '&amp;','<': '&lt;','>': '&gt;','"': '&quot;',"'": '&#39;','/': '&#x2F;','`': '&#x60;','=': '&#x3D;'})[s]);
Hühner
quelle
-2

Wenn Sie diese Informationen in einer Datenbank speichern , ist es falsch, HTML mithilfe eines clientseitigen Skripts zu maskieren . Dies sollte auf dem Server erfolgen . Andernfalls ist es einfach, Ihren XSS-Schutz zu umgehen.

Um meinen Standpunkt klar zu machen, hier ein Beispiel mit einer der Antworten:

Nehmen wir an, Sie verwenden die Funktion EscapeHtml, um das HTML aus einem Kommentar in Ihrem Blog zu entfernen und es dann auf Ihrem Server zu veröffentlichen.

var entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#39;',
    "/": '&#x2F;'
  };

  function escapeHtml(string) {
    return String(string).replace(/[&<>"'\/]/g, function (s) {
      return entityMap[s];
    });
  }

Der Benutzer könnte:

  • Bearbeiten Sie die POST-Anforderungsparameter und ersetzen Sie den Kommentar durch Javascript-Code.
  • Überschreiben Sie die Funktion EscapeHtml über die Browserkonsole.

Wenn der Benutzer dieses Snippet in die Konsole einfügt, wird die XSS-Validierung umgangen:

function escapeHtml(string){
   return string
}
Kauê Gimenes
quelle
Ich stimme dir nicht zu. Um diesen XSS-Schutz zu umgehen, müssten Sie einen XSS-Angriff verwenden (Einfügen eines Skripts, das das Escaping deaktiviert), das Sie tatsächlich blockieren. In bestimmten Fällen ist es tatsächlich besser, auf dem Client zu maskieren, z. B. wenn die Daten von einer REST-API stammen, die Standard-JSON zurückgeben muss.
ItalyPaleAle
@Qualcuno Wenn Sie diese Überprüfung im Client durchführen und diese Informationen an den Server senden, der darauf vertraut, dass sie überprüft wurden, kann der Benutzer die Anforderung einfach bearbeiten und das Skript wird in der Datenbank gespeichert.
Kauê Gimenes
@Qualcuno Ich habe einige Beispiele beigefügt, um meinen Standpunkt klarer zu machen.
Kauê Gimenes
1
Die Frage war, ob vom Server empfangene Zeichenfolgen maskiert werden sollen um sie im Browser anzuzeigen . Was Sie sagen, ist das Entkommen von Zeichenfolgen, bevor Sie sie an den Server
senden. Dies
@Qualcuno Dies ist eine beliebte Frage in Stackoverflow, und ich glaube, dies ist ein wichtiger Punkt, der behandelt werden muss. Deshalb habe ich geantwortet.
Kauê Gimenes
-2

Alle Lösungen sind nutzlos , wenn Sie wieder Flucht verhindern tun sie nicht, wie die meisten Lösungen halten würde entkommen &zu &amp;.

escapeHtml = function (s) {
    return s ? s.replace(
        /[&<>'"]/g,
        function (c, offset, str) {
            if (c === "&") {
                var substr = str.substring(offset, offset + 6);
                if (/&(amp|lt|gt|apos|quot);/.test(substr)) {
                    // already escaped, do not re-escape
                    return c;
                }
            }
            return "&" + {
                "&": "amp",
                "<": "lt",
                ">": "gt",
                "'": "apos",
                '"': "quot"
            }[c] + ";";
        }
    ) : "";
};
C Nimmanant
quelle
4
Dies wird als doppeltes Escapezeichen bezeichnet und sollte behoben werden, indem sichergestellt wird, dass Ihre Eingabedaten nicht bereits maskiert sind. Was wäre, wenn Sie & lt; an den Benutzer? Oder wird der Text vielleicht woanders wiederverwendet und hängt davon ab, ob die Flucht stattgefunden hat?
Thelem