L'encodage HTML est perdu lorsque l'attribut est lu dans le champ de saisie

J'utilise JavaScript pour extraire une valeur d'un champ caché et l'afficher dans une zone de texte. La valeur dans le champ caché est encodée.

Par exemple,

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

Est entraîné dans

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

Via jQuery pour obtenir la valeur du champ caché (c'est à ce moment-là que je perds le codage):

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

Le problème est que lorsque j'ai lu la chalk &amp; cheese chalk &amp; cheese du champ caché, JavaScript semble perdre le codage. Pour échapper " et ' , je veux que l'encodage reste.

Existe-t-il une bibliothèque JavaScript ou une méthode jQuery qui codera HTML une chaîne?

    J'utilise ces fonctions:

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

    Fondamentalement, un élément div est créé en mémoire, mais il n'est jamais ajouté au document.

    Sur la fonction htmlEncode , je définis le innerText de l'élément et récupère le innerHTML encodé; Sur la fonction htmlDecode , j'ai configuré la valeur innerHTML de l'élément et le innerText est récupéré.

    Vérifiez un exemple en cours d'exécution ici .

    L'astuce jQuery n'encourage pas les citations et, dans IE, elle enlèvera vos espaces.

    Basé sur le gabarit d' échappement dans Django, ce qui, je l'ai déjà, est fortement utilisé / testé, j'ai fait cette fonction qui fait ce qu'il faut.

    Il est sans doute plus simple (et peut-être plus rapide) que n'importe laquelle des solutions de contournement pour le problème de décollage des espaces blancs – et il encode des citations, ce qui est essentiel si vous utilisez le résultat dans une valeur d'attribut par exemple.

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

    Mise à jour 2013-06-17:
    Dans la recherche de l'échappement le plus rapide, j'ai trouvé cette implémentation d'une méthode replaceAll :
    http://dumpsite.com/forum/index.php?topic=4.msg29#msg29
    (Également référencé ici: méthode la plus rapide pour remplacer toutes les instances d'un caractère dans une chaîne )
    Quelques résultats de performance ici:
    http://jsperf.com/htmlencoderegex/25

    Il donne une chaîne de résultats identique aux chaînes de replace intégrées ci-dessus. Je serais très heureux si quelqu'un pouvait expliquer pourquoi c'est plus rapide!

    Mise à jour 2015-03-04:
    Je viens de remarquer que AngularJS utilise exactement la méthode ci-dessus:
    https://github.com/angular/angular.js/blob/v1.3.14/src/ngSanitize/sanitize.js#L435

    Ils ajoutent quelques raffinements: ils semblent gérer un problème Unicode obscur ainsi que la conversion de tous les caractères non alphanumériques en entités. J'étais sous l'impression que ce dernier n'était pas nécessaire tant que vous avez un jeu de caractères UTF8 spécifié pour votre document.

    Je noterai que (4 ans plus tard) Django ne fait toujours aucune de ces choses, donc je ne sais pas à quel point elles sont importantes:
    https://github.com/django/django/blob/1.8b1/django/utils/html.py#L44

    Mise à jour 2016-04-06:
    Vous voudrez peut-être également échapper à la barre avant / . Ceci n'est pas nécessaire pour un codage HTML correct, mais il est recommandé par OWASP comme une mesure de sécurité anti-XSS. (Merci à @JNF pour avoir suggéré cela dans les commentaires)

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

    Voici une version non jQuery qui est considérablement plus rapide que la version .replace() .html() et la version .replace() . Cela préserve tous les espaces, mais, comme la version jQuery, ne gère pas les guillemets.

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

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

    Test de vitesse

    Demo: JsFiddle

    Sortie:

    sortie

    Scénario:

     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> 

    Je sais que c'est un ancien, mais je voulais publier une variante de la réponse acceptée qui fonctionnera dans IE sans supprimer les lignes:

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

    Le soulignement fournit les _.escape() et _.unescape() qui le font.

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

    Bonne réponse. Notez que si la valeur à encoder est undefined ou null avec jQuery 1.4.2, vous pouvez obtenir des erreurs telles que:

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

    OU

    Uncaught TypeError: Object has no method 'html'

    La solution consiste à modifier la fonction pour vérifier une valeur réelle:

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

    Pour ceux qui préfèrent javascript, voici la méthode que j'ai utilisée avec succès:

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

    Prototype l' a intégré dans la classe String . Donc, si vous utilisez / planifiez d'utiliser Prototype, cela ressemble à quelque chose comme:

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

    FWIW, l'encodage n'est pas perdu. L'encodage est utilisé par l'analyseur de balisage (navigateur) pendant la charge de la page. Une fois que la source est lue et analysée et que le navigateur a le DOM chargé dans la mémoire, l'encodage a été analysé dans ce qu'il représente. Donc, lorsque votre JS est exécuté pour lire n'importe quoi dans la mémoire, le caractère qu'il obtient est ce que représente l'encodage.

    Je peux opérer strictement sur la sémantique ici, mais je voulais que vous compreniez le but du codage. Le mot «perdu» fait ressentir que quelque chose ne fonctionne pas comme il se doit.

    Plus rapide sans Jquery. Vous pouvez coder tous les caractères de votre chaîne:

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

    Ou cibler uniquement les personnages principaux à qui s'inquiéter (&, inebreaks, <,>, "et") comme:

     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> 

    Voici une solution javascript simple. Il étend l'objet String avec une méthode "HTMLEncode" qui peut être utilisée sur un objet sans paramètre ou avec un paramètre.

     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("æåøåæå")) 

    J'ai fait un gist "méthode HTMLEncode pour javascript" .

    J'ai eu un problème similaire et le encodeURIComponent utilisant la fonction encodeURIComponent de JavaScript ( documentation )

    Par exemple, dans votre cas si vous utilisez:

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

    et

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

    Vous obtiendrez de la chalk%20%26%20cheese . Même les espaces sont conservés.

    Dans mon cas, j'ai dû coder une barre oblique inverse et ce code fonctionne parfaitement

     encodeURIComponent('name/surname') 

    Et j'ai le name%2Fsurname

    Vous ne devriez pas avoir à échapper / coder des valeurs afin de les transférer d'un champ de saisie à l'autre.

     <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 n'intervient pas de HTML brut ou n'importe quoi; Il dit simplement au DOM de définir la value propriété (ou de l'attribut, pas sûr). Quoi qu'il en soit, le DOM gère tout problème de codage pour vous. Sauf si vous faites quelque chose d'étrange comme l'utilisation de document.write ou eval , le codage HTML sera effectivement transparent.

    Si vous parlez de générer une nouvelle boîte de texte pour contenir le résultat … c'est toujours aussi simple. Passez simplement la partie statique du HTML à jQuery, puis définissez le reste des propriétés / attributs sur l'objet qu'il vous renvoie.

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

    Afaik il n'y a pas de méthode HTML directe Encode / Decode en javascript.

    Cependant, ce que vous pouvez faire, c'est utiliser JS pour créer un élément arbitraire, définir le texte interne, puis le lire en utilisant innerHTML.

    Disons, avec jQuery cela devrait fonctionner:

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

    Ou quelque chose dans ce sens

    Si vous souhaitez utiliser jQuery. J'ai trouvé ça:

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

    (Partie du plugin jquery.string offerte par jQuery SDK)

    Le problème avec Prototype je crois est qu'il étend les objets de base en JavaScript et sera incompatible avec n'importe quel jQuery que vous avez pu utiliser. Bien sûr, si vous utilisez déjà Prototype et non jQuery, ce ne sera pas un problème.

    EDIT: Il existe également ceci, qui est un port de utilitaires de chaîne Prototype pour jQuery:

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

    Ceci provient du code source ExtJS.

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

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

    .htmlEncode () sera accessible sur toutes les chaînes une fois définies.

    HtmlEncode la valeur donnée

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

    Basé sur la désinfection angulaire … (syntaxe du module es6)

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

    J'ai rencontré des problèmes avec la barre oblique inverse dans ma chaîne Domain \ User.

    Je l'ai ajouté aux autres échappées de la réponse d'Anentropic

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

    Ce que j'ai trouvé ici: Comment échapper à la barre oblique inverse en JavaScript?