Frage

Ich bin mit JavaScript Wert zu ziehen, von einem versteckten Feld und es in einem Textfeld angezeigt werden soll. Der Wert in dem verborgenen Bereich codiert wird.

Beispiel:

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

wird gezogen in

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

über einige jQuery den Wert aus dem verborgenen Bereich zu bekommen (es ist an dieser Stelle, dass ich die Codierung verlieren):

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

Das Problem ist, dass, wenn ich chalk &amp; cheese aus dem verborgenen Feld lesen, JavaScript scheint die Codierung zu verlieren. Ich will nicht der Wert sein chalk & cheese. Ich möchte die wörtliche amp; zu erhalten.

Gibt es eine JavaScript-Bibliothek oder ein jQuery-Methode, die HTML-kodieren wird ein String?

War es hilfreich?

Lösung

EDIT: Diese Antwort wurde vor langer geschrieben, und die htmlDecode Funktion eine XSS-Schwachstelle eingeführt. Es wurde zu einem div Verringerung der XSS Chance, das temporäre Element Wechsel von einem textarea modifiziert. Aber heute möchte ich Sie ermutigen, die DOMParser API zu verwenden, wie in anderen anwswer vorgeschlagen.


Ich verwende 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();
}

Im Grunde ein div-Element wird im Speicher erstellt, aber es wird nie an das Dokument angehängt.

Auf der htmlEncode Funktion habe ich die innerText des Elements, und Abrufen des codierten innerHTML; auf der htmlDecode Funktion habe ich den innerHTML Wert des Elements und die innerText abgerufen werden.

überprüfen Sie ein laufendes Beispiel hier .

Andere Tipps

Die jQuery Trick kodieren keine Anführungszeichen und in IE wird es Ihre Leerzeichen abzustreifen.

Auf der Grundlage der entkommen TemplateTag in Django, die ich schätze, stark verwendet wird / bereits getestet, habe ich diese Funktion, die das tut, was gebraucht wird.

Es ist wohl einfacher (und möglicherweise auch schneller) als eine der Abhilfen für die Leer-Stripping Ausgabe - und es kodiert Anführungszeichen, die unerlässlich ist, wenn Sie das Ergebnis innerhalb eines Attributwertes zum Beispiel verwenden werden.

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, '&');
}

Aktualisieren 2013.06.17:
Bei der Suche nach dem schnellsten Entkommen habe ich diese Implementierung einer replaceAll Methode gefunden:
http://dumpsite.com/forum/index.php?topic=4 .msg29 # msg29
(Auch hier verwiesen: schnellste Methode, um alle Instanzen eines Zeichens in einem String zu ersetzen)
Einige Leistungsergebnisse hier:
http://jsperf.com/htmlencoderegex/25

Es gibt identischen Ergebnis-String an die builtin replace Ketten oben. Ich würde mich sehr freuen, wenn jemand erklären könnte, warum es schneller!?

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

Sie fügen hinzu, ein paar Verfeinerungen - sie scheinen eine obskuren Unicode Ausgabe sowie die Umwandlung aller nicht-alphanumerische Zeichen Einheiten. Ich habe den Eindruck, diese nicht notwendig war, solange Sie einen UTF8-Zeichensatz für das Dokument festgelegt haben.

Ich werde beachten Sie, dass (4 Jahre später) Django noch keine dieser Dinge tut, also bin ich nicht sicher, wie wichtig sie sind:
https://github.com/django/django/ Blob / 1.8b1 / django / utils / html.py # L44

Aktualisieren 2016.04.06:
Sie können auch Slash / entfliehen möchten. Dies ist nicht für die richtige HTML-Codierung erforderlich, jedoch wird es empfohlen von OWASP als Anti-XSS Sicherheitsmaßnahme. (Dank für die Annahme, diese in den Kommentaren @JNF)

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

Hier ist eine nicht-jQuery-Version, die als wesentlich schneller ist sowohl die jQuery .html() Version und die .replace() Version. Dies bewahrt alle Leerzeichen, aber wie die jQuery-Version, nicht Anführungszeichen behandeln.

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

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

  

Speed-Test

Demo:

Ausgabe:

Ausgang

Script:

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>

Ich weiß, das ist ein alter, aber ich wollte eine Variation von die akzeptierte Antwort dass in funktioniert IE ohne Entfernen Zeilen:

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

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

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

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

Gute Antwort. Beachten Sie, dass, wenn der Wert zu kodieren ist undefined oder null mit jQuery 1.4.2 Sie Fehler bekommen könnte wie:

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

oder

Uncaught TypeError: Object has no method 'html'

Die Lösung ist, die Funktion zu modifizieren, um einen tatsächlichen Wert zu überprüfen:

function htmlEncode(value){ 
    if (value) {
        return jQuery('<div/>').text(value).html(); 
    } else {
        return '';
    }
}

Für diejenigen, die schlicht Javascript bevorzugen, hier ist die Methode, die ich erfolgreich eingesetzt habe:

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

FWIW, ist die Codierung nicht verloren. Die Codierung wird durch den Markup-Parser (Browser) während der Seitenlast verwendet. Sobald die Quelle gelesen und analysiert, und der Browser den DOM in dem Speicher geladen wird die Codierung analysiert worden, was es darstellt. Also von der Zeit Ihre JS ist ausführen etwas in den Speicher zu lesen, die char es bekommt ist das, was die Codierung dargestellt.

ich streng auf Semantik hier in Betrieb sein kann, aber ich will Ihnen, den Zweck der Codierung verstehen. Das Wort „verloren“ macht es wie etwas klingt funktioniert nicht, wie es sollte.

Prototype hat es eingebaute in der String-Klasse . Also, wenn Sie mit / Plan Prototype zu verwenden, tut es so etwas wie:

'<div class="article">This is an article</div>'.escapeHTML();
// -> "&lt;div class="article"&gt;This is an article&lt;/div&gt;"

Schneller ohne JQuery. Sie können jedes Zeichen in der Zeichenfolge kodieren:

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

oder nur die Hauptfiguren Ziel zu befürchten (&, 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>

Hier ist eine einfache JavaScript-Lösung. Es erstreckt sich String-Objekt mit einer Methode „Htmlencode“, die auf ein Objekt ohne Parameter verwendet werden kann, oder mit einem Parameter.

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 Kern "Htmlencode-Methode für javascript" .

Basierend auf Winkel des sanieren ... (es6 Modul Syntax)

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

afaik es keine gerade nach vorne HTML Encode / Decode Methoden in Javascript ist.

Doch was Sie tun können, ist JS zu verwenden, um ein beliebiges Element zu erstellen, setzen Sie es innere Text, dann lesen sie innerHTML- verwenden.

sagen, mit jQuery sollte diese Arbeit:

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

oder etwas in diese Richtung

Sie sollten nicht zu entkommen / kodieren Werte, um sie von einem Eingabefeld zu einem anderen Shuttle.

<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 nicht roh HTML oder etwas gehen einzufügen; es sagt nur das DOM die value Eigenschaft (oder Attribut, nicht sicher) einzustellen. So oder so, behandelt das DOM keine Codierung Probleme für Sie. Es sei denn, Sie sind etwas seltsam wie mit document.write oder eval tun, HTML-Codierung wird effektiv transparent sein.

Wenn Sie sprechen über eine neue Textbox zu erzeugen um das Ergebnis zu halten ... es ist immer noch so einfach. Übergeben Sie einfach den statischen Teil der HTML jQuery, und dann den Rest der Eigenschaften / Attribute auf dem Objekt, um es Ihnen zurück.

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

Ich hatte ein ähnliches Problem und lösen es die Funktion encodeURIComponent von JavaScript verwenden ( Dokumentation )

Zum Beispiel, in Ihrem Fall, wenn Sie verwenden:

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

und

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

Sie werden chalk%20%26%20cheese erhalten. Auch Räume gehalten werden.

In meinem Fall hatte ich einen umgekehrten Schrägstrich zu kodieren und dieser Code funktioniert perfekt

encodeURIComponent('name/surname')

und ich habe name%2Fsurname

Meine pure-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 Encode & Decode

Wenn Sie jQuery verwenden möchten. Ich fand diese:

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

(Teil jquery.string Plugin von jQuery SDK angeboten)

Das Problem mit Prototype Ich glaube, dass es Basisobjekte in JavaScript erweitert und wird mit jeder jQuery unvereinbar Sie verwendet haben. wenn Sie bereits Natürlich verwenden Prototype und nicht jQuery, wird es kein Problem sein.

EDIT: Auch gibt es diese, die eine Portierung von Prototype String Dienstprogramme für jQuery ist:

http://stilldesigning.com/dotstring/

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 von ExtJS-Quellcode.

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

Will Ausgang: &lt;script&gt;alert(&quot;I hack your site&quot;)&lt;/script&gt;

.htmlEncode () wird auf allen Saiten zugänglich sein, wenn definiert ist.

HtmlEncodes der angegebene Wert

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

Ich lief in einige Probleme mit Backslash in meinem Domain \ User String.

Ich habe diese zu den anderen Fluchten aus Anentropic Antwort

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

Welche fand ich hier: Wie Backslash in JavaScript zu entkommen?

Hier ist ein wenig, das die Server.HTMLEncode Funktion von Microsofts ASP, geschrieben in reinen JavaScript emuliert:

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 nicht kodieren Apostrophe, aber codiert das andere HTML-Specials und alle Zeichen außerhalb des 0x20-0x7e Bereichs.

Picking was escapeHTML() in der prototype.js

tun

Durch Hinzufügen dieses Skript hilft Ihnen escape:

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

Jetzt können Sie escape Methode auf Strings in Ihrem Skript aufrufen, wie:

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

Hoffe, es hilft jemand eine einfache Lösung, ohne dass die gesamte prototype.js einschließen mit

einige der anderen Antworten verwenden hier habe ich eine Version, die unabhängig von der Anzahl der verschiedenen codierten Zeichen alle relevanten Zeichen in einem Durchlauf ersetzt (nur ein Aufruf an replace()) so für größere Saiten schneller wird.

Es beruht nicht auf dem DOM-API zu existieren oder auf anderen Bibliotheken.

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

Mit ran, die einmal, können Sie jetzt anrufen

encodeHTML('<>&"\'')

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

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top