web-dev-qa-db-fra.com

HtmlSpecialChars équivalent en Javascript?

Apparemment, c'est plus difficile à trouver que je ne le pensais. Et c'est même si simple ...

Existe-t-il une fonction équivalente à la fonction htmlspecialchars de PHP intégrée à Javascript? Je sais que c'est assez facile à mettre en œuvre vous-même, mais utiliser une fonction intégrée, si disponible, est tout simplement plus agréable.

Pour ceux qui ne connaissent pas PHP, htmlspecialchars traduit des éléments tels que <htmltag/> en &lt;htmltag/&gt;

Je sais que escape() et encodeURI() ne fonctionnent pas de cette façon.

143
Bart van Heukelom

Il y a un problème avec votre code de solution - il n'échappera que la première occurrence de chaque caractère spécial. Par exemple:

escapeHtml('Kip\'s <b>evil</b> "test" code\'s here');
Actual:   Kip&#039;s &lt;b&gt;evil</b> &quot;test" code's here
Expected: Kip&#039;s &lt;b&gt;evil&lt;/b&gt; &quot;test&quot; code&#039;s here

Voici le code qui fonctionne correctement:

function escapeHtml(text) {
  return text
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
}

Mettre à jour

Le code suivant produira des résultats identiques à ceux ci-dessus, mais il fonctionnera mieux, en particulier sur les gros blocs de texte (merci jbo5112 ).

function escapeHtml(text) {
  var map = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };

  return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}
285
Kip

C'est l'encodage HTML. Il n'y a pas de fonction javascript native pour le faire, mais vous pouvez google et en obtenir des joliment finies.

Par exemple. http://sanzon.wordpress.com/2008/05/01/neat-little-html-encoding-trick-in-javascript/

MODIFIER:
Voici ce que j'ai testé:

var div = document.createElement('div');
  var text = document.createTextNode('<htmltag/>');
  div.appendChild(text);
  console.log(div.innerHTML);

Sortie: &lt;htmltag/&gt;

29
o.k.w

A lire: http://bigdingus.com/2007/12/29/html-escaping-in-javascript/

escapeHTML: (function() {
 var MAP = {
   '&': '&amp;',
   '<': '&lt;',
   '>': '&gt;',
   '"': '&#34;',
   "'": '&#39;'
 };
  var repl = function(c) { return MAP[c]; };
  return function(s) {
    return s.replace(/[&<>'"]/g, repl);
  };
})()

Note: Ne lancez cette opération qu'une seule fois. Et ne l'exécutez pas sur des chaînes déjà encodées, par exemple. &amp; devient &amp;amp;

25
Chris Jacob

Avec jQuery ça peut être comme ça:

var escapedValue = $('<div/>').text(value).html();

Question connexe Échapper à des chaînes HTML avec jQuery

Comme mentionné dans les commentaires, les guillemets doubles et simples sont laissés tels quels pour cette implémentation. Cela signifie que cette solution ne doit pas être utilisée si vous devez créer un attribut d'élément sous forme de chaîne html brute.

19
Alexander Yanovets

Voici une fonction pour échapper au HTML:

function escapeHtml(str)
{
    var map =
    {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
    };
    return str.replace(/[&<>"']/g, function(m) {return map[m];});
}

Et à décoder:

function decodeHtml(str)
{
    var map =
    {
        '&amp;': '&',
        '&lt;': '<',
        '&gt;': '>',
        '&quot;': '"',
        '&#039;': "'"
    };
    return str.replace(/&amp;|&lt;|&gt;|&quot;|&#039;/g, function(m) {return map[m];});
}
15
Dan Bray

Underscore.js fournit une fonction pour cela:

_.escape(string)

Échappe une chaîne à insérer dans HTML en remplaçant les caractères &, <,>, "et '.

http://underscorejs.org/#escape

Ce n'est pas une fonction Javascript intégrée, mais si vous utilisez déjà Underscore, c'est une meilleure alternative que d'écrire votre propre fonction si vos chaînes à convertir ne sont pas trop grandes.

6
mer10z_tech

Une autre solution consiste à renoncer à tous les mappages de caractères et à convertir tous les caractères indésirables en leurs références numériques respectives, par exemple:

function escapeHtml(raw) {
    return raw.replace(/[&<>"']/g, function onReplace(match) {
        return '&#' + match.charCodeAt(0) + ';';
    });
}

Remarque que le RegEx spécifié ne traite que les caractères spécifiques que l'OP voulait échapper mais, en fonction du contexte d'utilisation du code HTML échappé, ces caractères peuvent ne pas être suffisants. Article de Ryan Grove L’échappement HTML ne se limite pas à &, <,>, et " est une excellente lecture du sujet. Et selon votre contexte, le RegEx suivant peut très bien être nécessaire pour éviter l’injection XSS:

var regex = /[&<>"'` !@$%()=+{}[\]]/g
5
Fredric
String.prototype.escapeHTML = function() {
        return this.replace(/&/g, "&amp;")
                   .replace(/</g, "&lt;")
                   .replace(/>/g, "&gt;")
                   .replace(/"/g, "&quot;")
                   .replace(/'/g, "&#039;");
    }

échantillon : 

var toto = "test<br>";
alert(toto.escapeHTML());
3
patrick

Les chances sont que vous n'avez pas besoin d'une telle fonction. Votre code étant déjà dans le navigateur *, vous pouvez accéder directement au DOM au lieu de générer et d’encoder du code HTML qui devra être décodé à l’arrière par le navigateur pour pouvoir être utilisé.

Utilisez la propriété innerText pour insérer du texte brut dans le DOM en toute sécurité et beaucoup plus rapidement que d'utiliser l'une des fonctions d'échappement présentées. Même plus vite que d’attribuer une chaîne statique pré-codée à innerHTML.

Utilisez classList pour éditer les classes, dataset pour définir les attributs data- et setAttribute pour les autres.

Tous ceux-ci géreront échapper pour vous. Plus précisément, aucun échappement n'est nécessaire et aucun encodage ne sera effectué en dessous **, puisque vous travaillez autour de HTML, la représentation textuelle de DOM.

// use existing element
var author = 'John "Superman" Doe <[email protected]>';
var el = document.getElementById('first');
el.dataset.author = author;
el.textContent = 'Author: '+author;

// or create a new element
var a = document.createElement('a');
a.classList.add('important');
a.href = '/search?q=term+"exact"&n=50';
a.textContent = 'Search for "exact" term';
document.body.appendChild(a);

// actual HTML code
console.log(el.outerHTML);
console.log(a.outerHTML);
.important { color: red; }
<div id="first"></div>

* Cette réponse n'est pas destinée aux utilisateurs JavaScript côté serveur (Node.js, etc. )

** Sauf si vous le convertissez explicitement en HTML par la suite. Par exemple. en accédant à innerHTML - c'est ce qui se produit lorsque vous exécutez $('<div/>').text(value).html(); suggéré dans d'autres réponses. Donc, si votre objectif final est d’insérer des données dans le document, faites-le deux fois. Vous pouvez également constater que dans le code HTML résultant, tout n'est pas codé, seul le minimum nécessaire à sa validité. Cela est fait en fonction du contexte, c'est pourquoi cette méthode jQuery ne code pas les guillemets et ne doit donc pas être utilisée comme un économe général. Un échappement de guillemets est nécessaire lorsque vous construisez HTML en tant que chaîne avec des données non fiables ou contenant des guillemets à la place de la valeur d'un attribut. Si vous utilisez l'API DOM, vous n'avez pas à vous soucier de vous échapper.

3
user

Pour les utilisateurs de Node.JS (ou les utilisateurs utilisant le moteur d'exécution Jade dans le navigateur), vous pouvez utiliser la fonction d'échappement de Jade.

require('jade').runtime.escape(...);

Cela ne sert à rien d'écrire vous-même si quelqu'un d'autre le maintient. :)

2
BMiner
function htmlEscape(str){
    return str.replace(/[&<>'"]/g,x=>'&#'+x.charCodeAt(0)+';')
}

Cette solution utilise le code numérique des caractères. Par exemple, < est remplacé par &#60;.

Bien que ses performances soient légèrement inférieures à la solution utilisant une carte , elle présente les avantages suivants:

  • Pas dépendant d'une bibliothèque ou d'un DOM
  • Assez facile à retenir (vous n'avez pas besoin de mémoriser les 5 caractères d'échappement HTML)
  • Petit code
  • Raisonnablement rapide (c'est toujours plus rapide que 5 chaînes remplacées)
0
user202729

Je développe un peu sur la réponse de o.k.w.

Vous pouvez utiliser les fonctions DOM du navigateur pour cela. 

var utils = {
    dummy: document.createElement('div'),
    escapeHTML: function(s) {
        this.dummy.textContent = s
        return this.dummy.innerHTML
    }
}

utils.escapeHTML('<escapeThis>&')

Ceci retourne &lt;escapeThis&gt;&amp;

Il utilise la fonction standard createElement pour créer un élément invisible, puis utilise la fonction textContent pour définir une chaîne comme contenu, puis innerHTML pour obtenir le contenu dans sa représentation HTML.

0
Jonas Eberle

J'espère que cela gagnera la course grâce à ses performances et surtout pas à une logique chaînée utilisant .replace ('&', '&'). Replace ('<', '<') ...

var mapObj = {
   '&':"&amp;",
   '<':"&lt;",
   '>':"&gt;",
   '"':"&quot;",
   '\'':"&#039;"
};
var re = new RegExp(Object.keys(mapObj).join("|"),"gi");

function escapeHtml(str) 
{   
    return str.replace(re, function(matched)
    {
        return mapObj[matched.toLowerCase()];
    });
}

console.log('<script type="text/javascript">alert('Hello World');</script>');
console.log(escapeHtml('<script type="text/javascript">alert('Hello World');</script>'));
0
Abdul Jabbar Dumrai

Inversé:

function decodeHtml(text) {
    return text
        .replace(/&amp;/g, '&')
        .replace(/&lt;/ , '<')
        .replace(/&gt;/, '>')
        .replace(/&quot;/g,'"')
        .replace(/&#039;/g,"'");
}
0
Gleb Dolzikov
function htmlspecialchars(str) {
 if (typeof(str) == "string") {
  str = str.replace(/&/g, "&amp;"); /* must do &amp; first */
  str = str.replace(/"/g, "&quot;");
  str = str.replace(/'/g, "&#039;");
  str = str.replace(/</g, "&lt;");
  str = str.replace(/>/g, "&gt;");
  }
 return str;
 }
0
user1477929