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

745

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

Par exemple,

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

se fait entraîner

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

via certains jQuery pour obtenir la valeur du champ caché (c'est à ce stade que je perds l'encodage):

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

Le problème est que lorsque je lis chalk &amp; cheesedans le champ caché, JavaScript semble perdre l'encodage. Je ne veux pas que la valeur soit chalk & cheese. Je veux que le littéral amp;soit conservé.

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

AJM
la source
Pouvez-vous montrer le Javascript que vous utilisez?
Sinan Taifour
1
ont ajouté comment j'obtiens de la valeur du champ caché
AJM
5
N'utilisez PAS la méthode innerHTML (la méthode jQuery .html () utilise innerHTML), comme sur certains navigateurs (je n'ai testé que Chrome), cela n'échappera pas aux guillemets, donc si vous mettiez votre valeur dans une valeur d'attribut , vous vous retrouveriez avec une vulnérabilité XSS.
James Roper
21
dans quel contexte est-elle chalket est- elle cheesejamais utilisée ensemble 0_o
d -_- b
2
@d -_- b lors de la comparaison de deux éléments. exemple. ils sont aussi différents que la craie et le fromage;)
Anurag

Réponses:

1067

EDIT: Cette réponse a été publiée il y a longtemps, et la htmlDecodefonction a introduit une vulnérabilité XSS. Il a été modifié en changeant l'élément temporaire de a diven une textarearéduction des chances XSS. Mais de nos jours, je vous encourage à utiliser l'API DOMParser comme suggéré dans d' autres réponses .


J'utilise ces fonctions:

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

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

Sur la htmlEncodefonction, j'ai défini l' innerTextélément de l'élément et récupéré l'encodé innerHTML; sur la htmlDecodefonction j'ai mis la innerHTMLvaleur de l'élément et le innerTextest récupéré.

Consultez un exemple en cours d'exécution ici .

CMS
la source
95
Cela fonctionne pour la plupart des scénarios, mais cette implémentation de htmlDecode éliminera tout espace supplémentaire. Ainsi, pour certaines valeurs de "input", input! = HtmlDecode (htmlEncode (input)). C'était un problème pour nous dans certains scénarios. Par exemple, si input = "<p> \ t Hi \ n There </p>", un encodage / décodage aller-retour donnera "<p> Hi There </p>". La plupart du temps, ça va, mais parfois ça ne l'est pas. :)
pettys
7
Merci pour la solution! J'ai résolu le problème de l'élimination des espaces blancs supplémentaires en remplaçant les nouvelles lignes par comme %% NL %% dans la valeur du texte, puis appelé .html () pour obtenir la valeur codée HTML, puis remplacé %% NL %% par <br /> ' s ... Pas à l'épreuve des balles mais a fonctionné et mes utilisateurs n'étaient pas susceptibles de taper %% NL %%.
benno
1
Ce qui est drôle, c'est que CSS a une white-spacepropriété, ce qui suggère comment les espaces dans le contenu HTML doivent être traités. La présence de la propriété implique que "ceci est préformaté, les espaces et les sauts de ligne doivent être préservés". Cela rompt la séparation du style et du contenu, car si vous essayez de reformater le HTML pour qu'il soit "joli" ou que vous le contourniez à travers un cycle d'encodage / décodage comme celui-ci, les séries d'espaces / sauts sont réduites et l'encodeur n'a pas façon de savoir si c'était correct de le faire, car il n'a pas connaissance de l' white-space:pre-*;indicateur dans un fichier CSS externe!
Triynko
2
Cette solution peut dépendre du fait que la page soit écrite en html ou xhtml, donc je préférerais une solution qui n'implique pas le DOM.
Phil H
30
Bien qu'il ait été répondu deux ans plus tard, la réponse de @Anentropic ci-dessous est meilleure à tous égards.
tchad
559

L'astuce jQuery ne code pas les guillemets et dans IE, elle supprimera votre espace.

Sur la base du templatetag d' échappement dans Django, qui je suppose est déjà largement utilisé / testé, j'ai créé cette fonction qui fait ce qui est nécessaire.

Il est sans doute plus simple (et peut-être plus rapide) que toutes les solutions de contournement pour le problème de suppression des espaces - et il code les guillemets, ce qui est essentiel si vous allez utiliser 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 replaceAllméthode:
http://dumpsite.com/forum/index.php?topic=4.msg29#msg29
(également référencé ici: Fastest méthode pour remplacer toutes les instances d'un caractère dans une chaîne )
Quelques résultats de performances ici:
http://jsperf.com/htmlencoderegex/25

Il donne une chaîne de résultat identique aux replacechaînes 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 améliorations - ils semblent gérer un problème Unicode obscur ainsi que convertir tous les caractères non alphanumériques en entités. J'avais l'impression que ce dernier n'était pas nécessaire tant que vous disposez d'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 pouvez également souhaiter échapper à la barre oblique /. Ceci n'est pas requis pour un encodage HTML correct, mais il est recommandé par OWASP comme mesure de sécurité anti-XSS. (merci à @JNF de l'avoir suggéré dans les commentaires)

        .replace(/\//g, '&#x2F;');
Anentropique
la source
3
Vous pouvez également utiliser &apos;au lieu de&#39;
Ferruccio
5
Merci, je n'ai jamais réalisé que ce &apos;n'était pas une entité HTML valide.
Ferruccio
10
Sans le /g, .replace()ne remplacera que le premier match.
ThinkingStiff
1
@ Tracker1 Je ne suis pas d'accord, si la fonction reçoit une entrée non valide, elle devrait générer une erreur. Si, dans un cas d'utilisation spécifique, vous souhaitez gérer les entrées non valides de cette manière, vérifiez la valeur avant d'appeler la fonction ou encapsulez l'appel de fonction dans un essai / capture.
Anentropic
80

Voici une version non jQuery qui est considérablement plus rapide que la .html()version jQuery et la .replace()version. 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 rapidité

Démo: jsFiddle

Production:

production

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>
ThinkingStiff
la source
17
Cela soulève la question: pourquoi n'est-ce pas déjà une fonction globale dans JS?!
SEoF
2
la .replace()version non regex récemment suggérée par @SEoF s'avère être beaucoup plus rapide: jsperf.com/htmlencoderegex/22
Anentropic
@Anentropic C'est en effet un éclairage rapide, mais je ne pense pas que cela fonctionne. Sans /g, .replace()ne fait que le premier match.
ThinkingStiff
intéressant dans Firefox, vous pouvez faire replace('a', 'b', 'g')ce qui fonctionne de la même manière que replace(/a/g, 'b')... la vitesse est également identique
Anentropic
1
moi non plus :) J'ai commencé juste à vouloir gérer les guillemets et je me suis retrouvé dans une quête de vitesse ...
Anentropic
32

Je sais que c'est une ancienne, 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();
} 
boca
la source
29

Underscore fournit _.escape()et _.unescape()méthodes qui le font.

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

> _.escape( "chalk & cheese" );
  "chalk &amp; cheese"
TJ VanToll
la source
Lodash a également une méthode similaire.
Gustavo Straube
12

Bonne réponse. Notez que si la valeur à coder est undefinedou nullavec 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 '';
    }
}
leepowers
la source
8
jQuery('<div/>').text(value || '').html()
roufamatic
3
@roufamatic - Nice one-liner. Mais la vérification d'un non-vide valueavec un ifenregistre d'avoir à créer un DIV à la volée et à saisir sa valeur. Cela peut être beaucoup plus performant si htmlEncodeon l'appelle beaucoup ET s'il est probable que ce valuesera vide.
leepowers
Salut ça ne fait pas β to & beta savez-vous pourquoi?
Dilip Rajkumar
11

Pour ceux qui préfèrent le javascript simple, 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;
}
timodius
la source
6

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

Je travaille peut-être strictement sur la sémantique ici, mais je voulais que vous compreniez le but de l'encodage. Le mot «perdu» donne l'impression que quelque chose ne fonctionne pas comme il se doit.

JAAulde
la source
6

Plus rapide sans Jquery. Vous pouvez encoder chaque caractère de votre chaîne:

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

Ou ciblez simplement les personnages principaux à craindre (&, 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>

Dave Brown
la source
5

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

'<div class="article">This is an article</div>'.escapeHTML();
// -> "&lt;div class="article"&gt;This is an article&lt;/div&gt;"
Sinan Taifour
la source
9
Après avoir regardé la solution de Prototype, c'est tout ce qu'il fait ... .replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); Assez facile.
Steve Wortham
5
ne devrait-il pas aussi faire quelque chose avec des guillemets? ce n'est pas bon
Anentropic
@Anentropic Je ne vois pas pourquoi il faudrait faire quoi que ce soit avec des guillemets; car les guillemets n'ont pas besoin d'être échappés sauf s'ils sont à l'intérieur d'une valeur d'attribut.
Andy
OK après réflexion, je reprends ce commentaire - si vous créez un morceau de HTML, vous voudriez en coder chaque partie, y compris les valeurs d'attribut, donc je suis d'accord avec Anentropic et je ne pense pas que la fonction Prototypejs soit suffisante dans ce cas.
Andy
4

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 résumé "Méthode HTMLEncode pour javascript" .

Netsi1964
la source
3

Basé sur angular's sanitize ... (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};
Tracker1
la source
Bien que j'aime vraiment cette réponse et en fait, je pense que c'est une bonne approche, j'ai un doute, est-ce que l'opérateur au niveau du bit sur if (value === null | value === undefined) return '';une faute de frappe ou en fait une fonctionnalité? Si oui, pourquoi utiliser celui-ci et non le commun ||? Je vous remercie!!
Alejandro Vales
1
@AlejandroVales Je suis sûr que c'était une faute de frappe ... corrigée.
Tracker1
1
Eh bien, gardez à l'esprit que le | mènera à 0 ou 1, donc en fait cela a fonctionné ^^
Alejandro Vales
ne pourriez-vous pas simplement utiliser == null? undefinedest la seule chose à avoir une équivalence null, donc deux triples égaux ne sont pas nécessaires de toute façon
Hashbrown
Ce n'est pas vrai du tout. nullet 0sont à la fois faux, oui, donc vous ne pouvez pas le faire !value, mais le but ==est de rendre certaines choses plus faciles. 0 == nullc'est faux. undefined == nullest vrai. vous pouvez juste fairevalue == null
Hashbrown
3

Pour autant que je sache, il n'y a pas de méthode HTML Encode / Decode simple en javascript.

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

Disons qu'avec jQuery, cela devrait fonctionner:

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

Ou quelque chose dans ce sens.

Ken Egozi
la source
Je trouve le downvote un peu amusant, étant donné que cette réponse est presque identique à celle qui a plus de 870 upvotes et a été publiée un peu après celle-ci.
Ken Egozi
2

Vous ne devriez pas avoir à échapper / encoder des valeurs pour les transférer d'un champ de saisie à un 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 ne va pas insérer du HTML brut ou quoi que ce soit; il indique simplement au DOM de définir la valuepropriété (ou l'attribut; pas sûr). Quoi qu'il en soit, le DOM gère tous les problèmes d'encodage pour vous. Sauf si vous faites quelque chose d'étrange comme l'utilisation de document.writeou eval, l'encodage HTML sera effectivement transparent.

Si vous parlez de générer une nouvelle zone de texte pour contenir le résultat ... c'est toujours aussi simple. Passez simplement la partie statique du code 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());
cHao
la source
2

J'ai eu un problème similaire et le résoudre en utilisant la fonction encodeURIComponentde JavaScript ( documentation )

Par exemple, dans votre cas si vous utilisez:

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

et

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

tu auras chalk%20%26%20cheese . Même les espaces sont conservés.

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

encodeURIComponent('name/surname')

et j'ai name%2Fsurname

Dmyan
la source
2

Voici un petit peu qui émule la Server.HTMLEncodefonction de l'ASP de Microsoft, écrit en JavaScript pur:

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

Le résultat n'encode pas les apostrophes, mais encode les autres spéciaux HTML et tout caractère en dehors de la plage 0x20-0x7e.

Récrire
la source
2

Ma fonction pure-JS:

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

Encodage et décodage d'entités HTML JavaScript

Nick Tsai
la source
1

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

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

(partie du plugin jquery.string offerte par le kit de développement logiciel jQuery)

Le problème avec le prototype, je crois, c'est qu'il étend les objets de base en JavaScript et sera incompatible avec tout jQuery que vous pourriez avoir utilisé. Bien sûr, si vous utilisez déjà Prototype et non jQuery, ce ne sera pas un problème.

EDIT: Il y a aussi ceci, qui est un port des utilitaires de chaîne de Prototype pour jQuery:

http://stilldesigning.com/dotstring/

Sam Saint-Pettersen
la source
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
    };
})();

Ceci provient du code source ExtJS.

WaiKit Kung
la source
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>

Sortira: &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.

Stuart Eske
la source
1

HtmlEncode la valeur donnée

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

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

J'ai ajouté ceci 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?

pain spatial
la source
0

Choisir ce qui escapeHTML()se passe dans le prototype.js

L'ajout de ce script vous aide à échapper au HTML:

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

vous pouvez maintenant appeler la méthode escapeHTML sur les chaînes de votre script, comme:

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

J'espère que cela aidera toute personne à la recherche d'une solution simple sans avoir à inclure l'intégralité du prototype.js

Sahith Vibudhi
la source
0

En utilisant certaines des autres réponses ici, j'ai fait une version qui remplace tous les caractères pertinents en une seule passe quel que soit le nombre de caractères codés distincts (un seul appel à replace() ), ce sera donc plus rapide pour les chaînes plus grandes.

Il ne dépend pas de l'API DOM pour exister ou d'autres bibliothèques.

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

Après l'avoir exécuté une fois, vous pouvez maintenant appeler

encodeHTML('<>&"\'')

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

Hashbrown
la source
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);

Israël
la source