HTML-Codierung verloren, wenn Attribut aus Eingabefeld gelesen wird

745

Ich verwende JavaScript, um einen Wert aus einem ausgeblendeten Feld herauszuholen und in einem Textfeld anzuzeigen. Der Wert im ausgeblendeten Feld wird codiert.

Zum Beispiel,

<input id='hiddenId' type='hidden' value='chalk &amp; cheese' />

wird hineingezogen

<input type='text' value='chalk &amp; cheese' />

über eine jQuery, um den Wert aus dem versteckten Feld zu erhalten (an diesem Punkt verliere ich die Codierung):

$('#hiddenId').attr('value')

Das Problem ist, dass chalk &amp; cheeseJavaScript beim Lesen aus dem versteckten Feld die Codierung zu verlieren scheint. Ich möchte nicht, dass der Wert ist chalk & cheese. Ich möchte, dass das Wort amp;beibehalten wird.

Gibt es eine JavaScript-Bibliothek oder eine jQuery-Methode, die eine Zeichenfolge HTML-codiert?

AJM
quelle
Können Sie das von Ihnen verwendete Javascript anzeigen?
Sinan Taifour
1
habe hinzugefügt, wie ich Wert aus verstecktem Feld bekomme
AJM
5
Verwenden Sie NICHT die innerHTML-Methode (die jQuery .html () -Methode verwendet innerHTML), da dies bei einigen (ich habe nur Chrome getestet) Browsern Anführungszeichen nicht entgeht. Wenn Sie also Ihren Wert in einen Attributwert einfügen Sie würden mit einer XSS-Sicherheitslücke enden.
James Roper
21
in welchem ​​Kontext wird chalkund cheesejemals zusammen verwendet 0_o
d -_- b
2
@d -_- b beim Vergleich zweier Elemente. Beispiel. Sie sind so unterschiedlich wie Kreide und Käse;)
Anurag

Antworten:

1067

BEARBEITEN: Diese Antwort wurde vor langer Zeit veröffentlicht und die htmlDecodeFunktion führte eine XSS-Sicherheitsanfälligkeit ein. Es wurde geändert div, textareaindem das temporäre Element von a geändert wurde , um die XSS-Chance zu verringern. Aber heutzutage würde ich Sie ermutigen, die DOMParser-API zu verwenden, wie in anderen Antworten vorgeschlagen .


Ich benutze diese Funktionen:

function htmlEncode(value){
  // Create a in-memory element, set its inner text (which is automatically encoded)
  // Then grab the encoded contents back out. The element never exists on the DOM.
  return $('<textarea/>').text(value).html();
}

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

Grundsätzlich wird ein Textbereichselement im Speicher erstellt, das jedoch niemals an das Dokument angehängt wird.

Auf der htmlEncodeFunktion setze ich das innerTextdes Elements und rufe das codierte ab innerHTML; Auf die htmlDecodeFunktion setze ich den innerHTMLWert des Elements und das innerTextwird abgerufen.

Prüfen Sie das laufende Beispiel hier .

CMS
quelle
95
Dies funktioniert in den meisten Szenarien, aber diese Implementierung von htmlDecode eliminiert zusätzliche Leerzeichen. Geben Sie für einige Werte von "input"! = HtmlDecode (htmlEncode (input)) ein. Dies war in einigen Szenarien ein Problem für uns. Wenn beispielsweise input = "<p> \ t Hi \ n There </ p>" ist, ergibt eine Roundtrip-Codierung / -Decodierung "<p> Hi There </ p>". Meistens ist das in Ordnung, aber manchmal nicht. :)
Pettys
7
Danke für die Lösung! Ich habe das Problem des zusätzlichen Leerraums beseitigt, indem ich neue Zeilen durch %% NL %% im Textwert ersetzt und dann .html () aufgerufen habe, um den HTML-codierten Wert zu erhalten. Dann habe ich %% NL %% durch <br /> 'ersetzt. s ... Nicht kugelsicher, aber funktioniert und meine Benutzer haben wahrscheinlich %% NL %% eingegeben.
Benno
1
Witzig ist, dass CSS eine white-spaceEigenschaft hat, die vorschlägt, wie Leerzeichen im HTML-Inhalt verarbeitet werden sollen. Das Vorhandensein der Eigenschaft impliziert, dass "dies vorformatiert ist, Leerzeichen und Zeilenumbrüche erhalten bleiben sollten". Dies unterbricht die Trennung von Stil und Inhalt, denn wenn Sie versuchen, den HTML-Code so zu formatieren, dass er "hübsch" ist, oder ihn durch einen Codierungs- / Decodierungszyklus wie diesen umrunden, werden Leerzeichen / Unterbrechungen reduziert, und der Encoder hat keine Art und Weise zu wissen, ob dies in Ordnung war, da der white-space:pre-*;Indikator in einer externen CSS-Datei nicht bekannt ist!
Triynko
2
Diese Lösung kann davon abhängen, ob die Seite als HTML oder Xhtml geschrieben ist. Daher würde ich eine Lösung bevorzugen, die das DOM nicht einbezieht.
Phil H
30
Obwohl es zwei Jahre später beantwortet wurde, ist die Antwort von @Anentropic unten in jeder Hinsicht besser.
Chad
559

Der jQuery-Trick codiert keine Anführungszeichen und entfernt im IE Ihre Leerzeichen.

Basierend auf dem Escape- Templatetag in Django, das meiner Meinung nach bereits stark genutzt / getestet wird, habe ich diese Funktion erstellt, die das tut, was benötigt wird.

Es ist wohl einfacher (und möglicherweise schneller) als alle Problemumgehungen für das Problem mit dem Leerzeichen-Stripping - und es codiert Anführungszeichen, was wichtig ist, wenn Sie das Ergebnis beispielsweise in einem Attributwert verwenden möchten.

function htmlEscape(str) {
    return str
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
}

// I needed the opposite function today, so adding here too:
function htmlUnescape(str){
    return str
        .replace(/&quot;/g, '"')
        .replace(/&#39;/g, "'")
        .replace(/&lt;/g, '<')
        .replace(/&gt;/g, '>')
        .replace(/&amp;/g, '&');
}

Update 2013-06-17:
Auf der Suche nach dem schnellsten Fluchtweg habe ich diese Implementierung einer replaceAllMethode gefunden:
http://dumpsite.com/forum/index.php?topic=4.msg29#msg29
(auch hier referenziert: Am schnellsten Methode zum Ersetzen aller Instanzen eines Zeichens in einer Zeichenfolge )
Einige Leistungsergebnisse hier:
http://jsperf.com/htmlencoderegex/25

Es gibt den oben eingebauten replaceKetten eine identische Ergebniszeichenfolge . Ich würde mich sehr freuen, wenn jemand erklären könnte, warum es schneller geht!?

Update 04.03.2015:
Ich habe gerade festgestellt, dass AngularJS genau die oben beschriebene Methode verwendet:
https://github.com/angular/angular.js/blob/v1.3.14/src/ngSanitize/sanitize.js#L435

Sie fügen einige Verbesserungen hinzu - sie scheinen ein obskures Unicode-Problem zu behandeln und alle nicht alphanumerischen Zeichen in Entitäten zu konvertieren. Ich hatte den Eindruck, dass Letzteres nicht erforderlich war, solange Sie einen UTF8-Zeichensatz für Ihr Dokument angegeben haben.

Ich werde feststellen, dass (4 Jahre später) Django immer noch keines dieser Dinge tut, daher bin ich mir nicht sicher, wie wichtig sie sind:
https://github.com/django/django/blob/1.8b1/django/utils /html.py#L44

Update 06.04.2016:
Möglicherweise möchten Sie auch dem Schrägstrich entkommen /. Dies ist für die korrekte HTML-Codierung nicht erforderlich, wird jedoch von OWASP als Anti-XSS-Sicherheitsmaßnahme empfohlen . (Danke an @JNF für den Vorschlag in den Kommentaren)

        .replace(/\//g, '&#x2F;');
Anentropisch
quelle
3
Sie können auch &apos;anstelle von&#39;
Ferruccio
5
Vielen Dank, ich habe nie bemerkt, dass dies &apos;keine gültige HTML-Entität ist.
Ferruccio
10
Ohne das /g, .replace()wird das erste Spiel nur ersetzen.
ThinkingStiff
1
@ Tracker1 Ich stimme nicht zu, wenn die Funktion ungültige Eingaben empfängt, sollte sie einen Fehler auslösen. Wenn Sie in einem bestimmten Anwendungsfall ungültige Eingaben auf diese Weise behandeln möchten, überprüfen Sie entweder den Wert, bevor Sie die Funktion aufrufen, oder schließen Sie den Funktionsaufruf in einen try / catch ein.
Anentropic
80

Hier ist eine Nicht-jQuery-Version, die erheblich schneller ist als jQuery .html() Version und die .replace()Version. Dadurch bleiben alle Leerzeichen erhalten, aber wie in der jQuery-Version werden keine Anführungszeichen verarbeitet.

function htmlEncode( html ) {
    return document.createElement( 'a' ).appendChild( 
        document.createTextNode( html ) ).parentNode.innerHTML;
};

Geschwindigkeit: http://jsperf.com/htmlencoderegex/17

Geschwindigkeitstest

Demo: jsFiddle

Ausgabe:

Ausgabe

Skript:

function htmlEncode( html ) {
    return document.createElement( 'a' ).appendChild( 
        document.createTextNode( html ) ).parentNode.innerHTML;
};

function htmlDecode( html ) {
    var a = document.createElement( 'a' ); a.innerHTML = html;
    return a.textContent;
};

document.getElementById( 'text' ).value = htmlEncode( document.getElementById( 'hidden' ).value );

//sanity check
var html = '<div>   &amp; hello</div>';
document.getElementById( 'same' ).textContent = 
      'html === htmlDecode( htmlEncode( html ) ): ' 
    + ( html === htmlDecode( htmlEncode( html ) ) );

HTML:

<input id="hidden" type="hidden" value="chalk    &amp; cheese" />
<input id="text" value="" />
<div id="same"></div>
ThinkingStiff
quelle
17
Dies wirft die Frage auf: Warum ist es in JS nicht bereits eine globale Funktion?!
SEoF
2
Die .replace()kürzlich von @SEoF vorgeschlagene Nicht-Regex- Version ist massiv schneller: jsperf.com/htmlencoderegex/22
Anentropic
@Anentropic Das leuchtet zwar schnell, aber ich glaube nicht, dass es funktioniert. Ohne /g, .replace()tut nur das erste Spiel.
ThinkingStiff
Interessanterweise können Sie in Firefox tun, replace('a', 'b', 'g')was genauso funktioniert wie replace(/a/g, 'b')... Geschwindigkeit ist aber auch identisch
Anentropic
1
Ich auch nicht :) Ich wollte zunächst nur mit Anführungszeichen umgehen und war auf der Suche nach Geschwindigkeit ...
Anentropic
32

Ich weiß, dass dies eine alte ist, aber ich wollte eine Variation der akzeptierten Antwort veröffentlichen , die im IE funktioniert, ohne Zeilen zu entfernen:

function multiLineHtmlEncode(value) {
    var lines = value.split(/\r\n|\r|\n/);
    for (var i = 0; i < lines.length; i++) {
        lines[i] = htmlEncode(lines[i]);
    }
    return lines.join('\r\n');
}

function htmlEncode(value) {
    return $('<div/>').text(value).html();
} 
Boca
quelle
29

Unterstrich bietet _.escape()und _.unescape()Methoden, die dies tun.

> _.unescape( "chalk &amp; cheese" );
  "chalk & cheese"

> _.escape( "chalk & cheese" );
  "chalk &amp; cheese"
TJ VanToll
quelle
Lodash hat auch eine ähnliche Methode.
Gustavo Straube
12

Gute Antwort. Beachten Sie, dass bei einem zu codierenden Wert undefinedoder nullmit jQuery 1.4.2 möglicherweise folgende Fehler auftreten:

jQuery("<div/>").text(value).html is not a function

ODER

Uncaught TypeError: Object has no method 'html'

Die Lösung besteht darin, die Funktion zu ändern, um nach einem tatsächlichen Wert zu suchen:

function htmlEncode(value){ 
    if (value) {
        return jQuery('<div/>').text(value).html(); 
    } else {
        return '';
    }
}
Leepowers
quelle
8
jQuery('<div/>').text(value || '').html()
Roufamatic
3
@roufamatic - Schöner Einzeiler. Aber die Überprüfung für einen nicht-leer valuemit einem iferspart ein DIV on the fly zu erstellen und den Wert greifen. Dies kann viel performanter sein, wenn htmlEncodeviel aufgerufen wird UND wenn es wahrscheinlich valueleer ist.
Leepowers
Hallo, es macht kein β zu & Beta. Weißt du warum?
Dilip Rajkumar
11

Für diejenigen, die einfaches Javascript bevorzugen, ist hier die Methode, die ich erfolgreich angewendet habe:

function escapeHTML (str)
{
    var div = document.createElement('div');
    var text = document.createTextNode(str);
    div.appendChild(text);
    return div.innerHTML;
}
Timodius
quelle
6

FWIW, die Codierung geht nicht verloren. Die Codierung wird vom Markup-Parser (Browser) beim Laden der Seite verwendet. Sobald die Quelle gelesen und analysiert wurde und der Browser das DOM in den Speicher geladen hat, wurde die Codierung in das analysiert, was sie darstellt. Wenn Ihr JS ausgeführt wird, um etwas im Speicher zu lesen, entspricht das Zeichen der Codierung.

Ich arbeite hier möglicherweise ausschließlich mit Semantik, aber ich wollte, dass Sie den Zweck der Codierung verstehen. Das Wort "verloren" lässt es so klingen, als ob etwas nicht so funktioniert, wie es sollte.

JAAulde
quelle
6

Schneller ohne Jquery. Sie können jedes Zeichen in Ihrer Zeichenfolge codieren:

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

Oder zielen Sie einfach auf die Hauptfiguren ab, über die Sie sich Sorgen machen möchten (&, Inebreaks, <,>, "und '), wie:

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

test.value=encode('Encode HTML entities!\n\n"Safe" escape <script id=\'\'> & useful in <pre> tags!');

testing.innerHTML=test.value;

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55"></textarea>

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

Dave Brown
quelle
5

In Prototype ist die String-Klasse integriert . Wenn Sie also Prototype verwenden / planen, dies zu tun, geschieht Folgendes:

'<div class="article">This is an article</div>'.escapeHTML();
// -> "&lt;div class="article"&gt;This is an article&lt;/div&gt;"
Sinan Taifour
quelle
9
Nachdem Sie sich die Lösung von Prototype angesehen haben, ist dies alles, was es tut ... .replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); Einfach genug.
Steve Wortham
5
sollte es nicht auch etwas mit Anführungszeichen tun? das ist nicht gut
Anentropic
@Anentropic Ich verstehe nicht, warum es irgendetwas mit Anführungszeichen tun müsste; Anführungszeichen müssen nur maskiert werden, wenn sie sich innerhalb eines Attributwerts befinden.
Andy
OK, nach einigem Nachdenken nehme ich diesen Kommentar zurück - wenn Sie ein Stück HTML erstellen, möchten Sie jeden Teil davon einschließlich der Attributwerte codieren, daher stimme ich Anentropic zu und denke nicht, dass die Prototypejs-Funktion in ausreichend ist dieser Fall.
Andy
4

Hier ist eine einfache Javascript-Lösung. Es erweitert das String-Objekt um eine Methode "HTMLEncode", die für ein Objekt ohne Parameter oder mit einem Parameter verwendet werden kann.

String.prototype.HTMLEncode = function(str) {
  var result = "";
  var str = (arguments.length===1) ? str : this;
  for(var i=0; i<str.length; i++) {
     var chrcode = str.charCodeAt(i);
     result+=(chrcode>128) ? "&#"+chrcode+";" : str.substr(i,1)
   }
   return result;
}
// TEST
console.log("stetaewteaw æø".HTMLEncode());
console.log("stetaewteaw æø".HTMLEncode("æåøåæå"))

Ich habe eine wesentliche "HTMLEncode-Methode für Javascript" erstellt .

Netsi1964
quelle
3

Basierend auf der Desinfektion von Angular ... (es6-Modulsyntax)

// ref: https://github.com/angular/angular.js/blob/v1.3.14/src/ngSanitize/sanitize.js
const SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
const NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;

const decodeElem = document.createElement('pre');


/**
 * Decodes html encoded text, so that the actual string may
 * be used.
 * @param value
 * @returns {string} decoded text
 */
export function decode(value) {
  if (!value) return '';
  decodeElem.innerHTML = value.replace(/</g, '&lt;');
  return decodeElem.textContent;
}


/**
 * Encodes all potentially dangerous characters, so that the
 * resulting string can be safely inserted into attribute or
 * element text.
 * @param value
 * @returns {string} encoded text
 */
export function encode(value) {
  if (value === null || value === undefined) return '';
  return String(value).
    replace(/&/g, '&amp;').
    replace(SURROGATE_PAIR_REGEXP, value => {
      var hi = value.charCodeAt(0);
      var low = value.charCodeAt(1);
      return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
    }).
    replace(NON_ALPHANUMERIC_REGEXP, value => {
      return '&#' + value.charCodeAt(0) + ';';
    }).
    replace(/</g, '&lt;').
    replace(/>/g, '&gt;');
}

export default {encode,decode};
Tracker1
quelle
Obwohl mir diese Antwort wirklich gefällt und ich denke, dass dies ein guter Ansatz ist, habe ich Zweifel, ist der bitweise Operator if (value === null | value === undefined) return '';eines Tippfehlers oder tatsächlich eine Funktion? Wenn ja, warum diese verwenden und nicht die übliche ||? Vielen Dank!!
Alejandro Vales
1
@AlejandroVales Ich bin mir ziemlich sicher, dass es ein Tippfehler war ... korrigiert.
Tracker1
1
Na jedenfalls daran denken, dass die | wird zu 0 oder 1 führen, also hat es tatsächlich funktioniert ^^
Alejandro Vales
könntest du nicht einfach benutzen == null? undefinedist das einzige, mit dem man Äquivalenz hat null, also sind zwei Triple-Equals sowieso nicht notwendig
Hashbrown
das stimmt überhaupt nicht. nullund 0sind beide falsch, ja, also kann man es nicht einfach tun !value, aber der springende Punkt ==ist, bestimmte Dinge einfacher zu machen. 0 == nullist falsch. undefined == nullist wahr. Sie können einfach tunvalue == null
Hashbrown
3

Soweit ich weiß, gibt es in Javascript keine einfache HTML-Encode / Decode-Methode.

Sie können jedoch JS verwenden, um ein beliebiges Element zu erstellen, seinen inneren Text festzulegen und ihn dann mit innerHTML zu lesen.

Angenommen, mit jQuery sollte dies funktionieren:

var helper = $('chalk & cheese').hide().appendTo('body');
var htmled = helper.html();
helper.remove();

Oder etwas in diese Richtung.

Ken Egozi
quelle
Ich finde die Abwertung ein wenig amüsant, wenn man bedenkt, dass diese Antwort fast identisch mit der ist, die über 870 positive Stimmen hat und etwas später veröffentlicht wurde.
Ken Egozi
2

Sie sollten keine Werte maskieren / codieren müssen, um sie von einem Eingabefeld in ein anderes zu verschieben.

<form>
 <input id="button" type="button" value="Click me">
 <input type="hidden" id="hiddenId" name="hiddenId" value="I like cheese">
 <input type="text" id="output" name="output">
</form>
<script>
    $(document).ready(function(e) {
        $('#button').click(function(e) {
            $('#output').val($('#hiddenId').val());
        });
    });
</script>

JS fügt kein rohes HTML oder ähnliches ein. Es weist das DOM lediglich an, die valueEigenschaft (oder das Attribut; nicht sicher) festzulegen. In beiden Fällen behandelt das DOM alle Codierungsprobleme für Sie. Wenn Sie nicht etwas Seltsames wie document.writeoder verwenden eval, ist die HTML-Codierung effektiv transparent.

Wenn Sie über das Generieren eines neuen Textfelds für das Ergebnis sprechen, ist dies immer noch genauso einfach. Übergeben Sie einfach den statischen Teil des HTML-Codes an jQuery und legen Sie die restlichen Eigenschaften / Attribute für das Objekt fest, das an Sie zurückgegeben wird.

$box = $('<input type="text" name="whatever">').val($('#hiddenId').val());
cHao
quelle
2

Ich hatte ein ähnliches Problem und löste es mit der Funktion encodeURIComponentaus JavaScript ( Dokumentation) )

Zum Beispiel in Ihrem Fall, wenn Sie verwenden:

<input id='hiddenId' type='hidden' value='chalk & cheese' />

und

encodeURIComponent($('#hiddenId').attr('value'))

du wirst bekommen chalk%20%26%20cheese. Auch Räume bleiben erhalten.

In meinem Fall musste ich einen Backslash codieren und dieser Code funktioniert perfekt

encodeURIComponent('name/surname')

und ich bekam name%2Fsurname

Dmyan
quelle
2

Hier ist ein kleines Stück, das die Server.HTMLEncodeFunktion von Microsoft ASP emuliert , die in reinem JavaScript geschrieben ist:

function htmlEncode(s) {
  var ntable = {
    "&": "amp",
    "<": "lt",
    ">": "gt",
    "\"": "quot"
  };
  s = s.replace(/[&<>"]/g, function(ch) {
    return "&" + ntable[ch] + ";";
  })
  s = s.replace(/[^ -\x7e]/g, function(ch) {
    return "&#" + ch.charCodeAt(0).toString() + ";";
  });
  return s;
}

Das Ergebnis codiert keine Apostrophe, sondern die anderen HTML-Specials und alle Zeichen außerhalb des Bereichs 0x20-0x7e.

Umschreiben
quelle
2

Meine reine JS-Funktion:

/**
 * HTML entities encode
 *
 * @param {string} str Input text
 * @return {string} Filtered text
 */
function htmlencode (str){

  var div = document.createElement('div');
  div.appendChild(document.createTextNode(str));
  return div.innerHTML;
}

JavaScript HTML Entities Encod & Decode

Nick Tsai
quelle
1

Wenn Sie jQuery verwenden möchten. Ich habe das gefunden:

http://www.jquerysdk.com/api/jQuery.htmlspecialchars

(Teil des vom jQuery SDK angebotenen Plugins jquery.string)

Ich glaube, das Problem mit Prototype ist, dass es Basisobjekte in JavaScript erweitert und nicht mit der von Ihnen verwendeten jQuery kompatibel ist. Wenn Sie bereits Prototype und nicht jQuery verwenden, ist dies natürlich kein Problem.

BEARBEITEN: Es gibt auch dies, einen Port der String-Dienstprogramme von Prototype für jQuery:

http://stilldesigning.com/dotstring/

Sam Saint-Pettersen
quelle
1
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
    };
})();

Dies ist aus ExtJS-Quellcode.

WaiKit Kung
quelle
1
<script>
String.prototype.htmlEncode = function () {
    return String(this)
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');

}

var aString = '<script>alert("I hack your site")</script>';
console.log(aString.htmlEncode());
</script>

Wird ausgegeben: &lt;script&gt;alert(&quot;I hack your site&quot;)&lt;/script&gt;

Auf .htmlEncode () kann auf alle einmal definierten Zeichenfolgen zugegriffen werden.

Stuart Eske
quelle
1

HtmlEncodes den angegebenen Wert

  var htmlEncodeContainer = $('<div />');
  function htmlEncode(value) {
    if (value) {
      return htmlEncodeContainer.text(value).html();
    } else {
      return '';
    }
  }
Himmel Yip
quelle
1

Ich habe einige Probleme mit dem Backslash in meiner Domain \ User-Zeichenfolge festgestellt.

Ich habe dies zu den anderen Fluchten aus Anentropics Antwort hinzugefügt

.replace(/\\/g, '&#92;')

Was ich hier gefunden habe: Wie kann ich einem Backslash in JavaScript entkommen?

Weltraumbrot
quelle
0

Auswählen, was escapeHTML()in der prototype.js getan wird

Durch Hinzufügen dieses Skripts können Sie HTML entkommen:

String.prototype.escapeHTML = function() { 
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
}

Jetzt können Sie die EscapeHTML-Methode für Zeichenfolgen in Ihrem Skript aufrufen, z.

var escapedString = "<h1>this is HTML</h1>".escapeHTML();
// gives: "&lt;h1&gt;this is HTML&lt;/h1&gt;"

Ich hoffe, es hilft jedem, der nach einer einfachen Lösung sucht, ohne den gesamten prototype.js einbeziehen zu müssen

Sahith Vibudhi
quelle
0

Unter Verwendung einiger der anderen Antworten hier habe ich eine Version erstellt, die alle relevanten Zeichen in einem Durchgang ersetzt, unabhängig von der Anzahl der verschiedenen codierten Zeichen (nur ein Aufruf von replace()), sodass sie für größere Zeichenfolgen schneller sind.

Es ist nicht auf die vorhandene DOM-API oder andere Bibliotheken angewiesen.

window.encodeHTML = (function() {
    function escapeRegex(s) {
        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    }
    var encodings = {
        '&'  : '&amp;',
        '"'  : '&quot;',
        '\'' : '&#39;',
        '<'  : '&lt;',
        '>'  : '&gt;',
        '\\' : '&#x2F;'
    };
    function encode(what) { return encodings[what]; };
    var specialChars = new RegExp('[' +
        escapeRegex(Object.keys(encodings).join('')) +
    ']', 'g');

    return function(text) { return text.replace(specialChars, encode); };
})();

Nachdem Sie das einmal ausgeführt haben, können Sie jetzt anrufen

encodeHTML('<>&"\'')

Bekommen &lt;&gt;&amp;&quot;&#39;

Hashbrown
quelle
0

function encodeHTML(str) {
    return document.createElement("a").appendChild( 
        document.createTextNode(str)).parentNode.innerHTML;
};

function decodeHTML(str) {
    var element = document.createElement("a"); 
    element.innerHTML = str;
    return element.textContent;
};
var str = "<"
var enc = encodeHTML(str);
var dec = decodeHTML(enc);
console.log("str: " + str, "\nenc: " + enc, "\ndec: " + dec);

Israel
quelle