632 votes

Échapper aux chaînes HTML avec jQuery

Quelqu'un connaît-il un moyen facile d'échapper à l'HTML à partir de chaînes de caractères dans le fichier jQuery ? J'ai besoin de pouvoir passer une chaîne arbitraire et qu'elle soit correctement échappée pour être affichée dans une page HTML (pour éviter les attaques par injection JavaScript/HTML). Je suis sûr qu'il est possible d'étendre jQuery pour faire cela, mais je ne connais pas assez le framework pour le moment pour réaliser cela.

0 votes

Voir aussi perf : jsperf.com/

633voto

Tom Gruner Points 3570

Il y a également la solution de mustache.js

var entityMap = {
  '&': '&',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#39;',
  '/': '&#x2F;',
  '`': '&#x60;',
  '=': '&#x3D;'
};

function escapeHtml (string) {
  return String(string).replace(/[&<>"'`=\/]/g, function (s) {
    return entityMap[s];
  });
}

7 votes

Notez que, curieusement, ' est mis en correspondance avec une entité ayant un décimal alors que / utilise le hexagone format.

52 votes

Cela devrait être la réponse acceptée - elle est simple, efficace, ne nécessite pas de dépendances et fait exactement ce qui est prévu, sans bidouillages obscurs.

6 votes

Quelle est l'orientation de la conversion \n a <br> ?

459voto

travis Points 14676

Puisque vous utilisez jQuery vous pouvez simplement définir l'élément text propriété :

// before:
// <div class="someClass">text</div>
var someHtmlString = "<script>alert('hi!');</script>";

// set a DIV's text:
$("div.someClass").text(someHtmlString);
// after: 
// <div class="someClass">&lt;script&gt;alert('hi!');&lt;/script&gt;</div>

// get the text in a string:
var escaped = $("<div>").text(someHtmlString).html();
// value: 
// &lt;script&gt;alert('hi!');&lt;/script&gt;

60 votes

Vous n'avez pas compris que vous devez accéder à $("div.someClass").html() pour faire sortir la version échappée.

16 votes

Ce n'est pas sûr pour les navigateurs croisés si votre chaîne de caractères comporte des espaces et que \n \r \t les caractères qu'il contient

1 votes

@nivcaner pouvez-vous donner (ou mettre un lien vers) un exemple d'échec ?

185voto

Henrik N Points 4447
$('<div/>').text('This is fun & stuff').html(); // "This is fun &amp; stuff"

Source : http://debuggable.com/posts/encode-html-entities-with-jquery:480f4dd6-13cc-4ce9-8071-4710cbdd56cb

11 votes

Comme indiqué dans la réponse ci-dessus, cette solution ne garantit pas la préservation des espaces blancs.

49 votes

Il convient de noter que cela ne permet pas d'échapper aux guillemets simples ou doubles. Si vous envisagez de placer la valeur dans un attribut HTML, cela peut poser un problème.

6 votes

@Kip : @travis a trouvé que la méthode de jQuery attr() (à partir de la version 1.8.3 au moins) effectue son propre encodage, de sorte que les chaînes non encodées peuvent être passées à la méthode directement ; par exemple : $('<div/>').attr('test-attr', '\'Tis "fun" & stuff')[0].outerHTML

61voto

tghw Points 14244

Si vous vous évadez pour le HTML, il n'y en a que trois auxquels je pense qui seraient vraiment nécessaires :

html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");

En fonction de votre cas d'utilisation, vous pouvez également avoir besoin de faire des choses comme " a &quot; . Si la liste était assez grande, j'utiliserais simplement un tableau :

var escaped = html;
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]
for(var item in findReplace)
    escaped = escaped.replace(findReplace[item][0], findReplace[item][1]);

encodeURIComponent() ne l'échappera que pour les URL, pas pour le HTML.

13 votes

Cette expression régulière produira des résultats étranges si le HTML en question comporte déjà des entités échappées. Par exemple, l'échappement de "Tom & Jerry" produira "Tom &amp ; Jerry".

12 votes

Veuillez utiliser var de déclarer item localement ; de toute façon, n'utilisez pas un for … in pas de boucle du tout lors du bouclage d'un tableau ! Utilisez une boucle ordinaire for à la place. Oh, et c'est encodeURIComponent pas escapeURIComponent .

3 votes

Si vous travaillez avec des attributs de balises, vous devrez également échapper aux guillemets et/ou aux doubles guillemets. La documentation PHP de htmlspecialchars contient une liste utile des conversions qu'il effectue. php.net/htmlspecialchars

37voto

zrajm Points 509

J'ai écrit une toute petite fonction qui fait cela. Elle n'échappe que " , & , < y > (mais c'est généralement tout ce dont vous avez besoin de toute façon). Elle est légèrement plus élégante que les solutions proposées précédemment car elle n'utilise que la fonction un .replace() pour faire toute la conversion. ( EDIT 2 : Réduction de la complexité du code, ce qui rend la fonction encore plus petite et plus nette. Si vous êtes curieux de connaître le code original, voir la fin de cette réponse).

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&<>]/g, function (a) {
        return { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' }[a];
    });
}

Il s'agit d'un simple Javascript, sans jQuery.

Échapper à / y ' trop

Modifier en réponse à mklement commentaire.

La fonction ci-dessus peut facilement être étendue pour inclure n'importe quel caractère. Pour spécifier plus de caractères à échapper, il suffit de les insérer tous les deux dans la classe de caractères de l'expression régulière (c'est-à-dire à l'intérieur du champ /[...]/g ) et comme entrée dans le chr objet. ( EDIT 2 : J'ai également raccourci cette fonction, de la même manière).

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&'\/<>]/g, function (a) {
        return {
            '"': '&quot;', '&': '&amp;', "'": '&#39;',
            '/': '&#47;',  '<': '&lt;',  '>': '&gt;'
        }[a];
    });
}

Notez l'utilisation ci-dessus de &#39; pour apostrophe (l'entité symbolique &apos; aurait pu être utilisé à la place - il est défini en XML, mais n'était pas inclus à l'origine dans la spécification HTML et pourrait donc ne pas être pris en charge par tous les navigateurs. Voir : Article Wikipedia sur les codages de caractères HTML ). Je me souviens également avoir lu quelque part que l'utilisation d'entités décimales est mieux supportée que l'utilisation d'entités hexadécimales, mais je ne parviens pas à trouver la source de cette information. (Et il ne doit pas y avoir beaucoup de navigateurs qui ne supportent pas les entités hexadécimales).

Note : Ajout de / y ' à la liste des caractères échappés n'est pas si utile, puisqu'ils n'ont pas de signification particulière en HTML et ne sont pas besoin de pour s'échapper.

Original escapeHtml Fonction

EDIT 2 : La fonction originale utilisait une variable ( chr ) pour stocker l'objet nécessaire à la .replace() callback. Cette variable avait également besoin d'une fonction anonyme supplémentaire pour l'étendre, ce qui rendait la fonction (inutilement) un peu plus grande et plus complexe.

var escapeHtml = (function () {
    'use strict';
    var chr = { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };
    return function (text) {
        return text.replace(/[\"&<>]/g, function (a) { return chr[a]; });
    };
}());

Je n'ai pas testé laquelle des deux versions est la plus rapide. Si vous le faites, n'hésitez pas à ajouter des informations et des liens à ce sujet ici.

0 votes

Merci d'avoir pris le temps, @Zrajm. Bon point sur le fait de ne pas avoir besoin de l'échappement ; une idée de la raison pour les deux. mustache.js y underscore.js le faire ? Pour ce qui est de ce dernier, il ne reconnaît que les entités numériques (qui représentent ' y / '), dans le hexagone majuscule lorsque un s'échapper. Ainsi, le texte échappé dans mustache.js - qui utilise curieusement un mélange de formats hexagonaux et décimaux - ne serait pas correctement désencapsulée dans underscore.js . Je me demande comment les autres bibliothèques populaires gèrent ce problème.

1 votes

La forme hexagonale minuscule est la plus supportée, c'est donc (probablement) la forme que les bibliothèques doivent convertir. a . (Bien sûr, les deux formes devraient fonctionner lors de la conversion de de .) - Apostrophes ' ont une sorte de fonction réservée dans le XML (et donc le XHTML, j'imagine ?), c'est pourquoi le XML (mais pas le HTML) a l'entité nommée &apos; . Je ne sais pas exactement pourquoi ou de quelle manière il est "réservé". - Les barres obliques sont spéciales dans les URLs, mais cela ne veut pas dire qu'elles sont réservées. en fait les justifier pour les inclure dans le codage HTML (le codage des URL étant quelque chose de complètement différent).

0 votes

Re &apos; : correct : utilisation sûre uniquement dans XHTML ; directement de la bouche du crowd-source - C'est moi qui souligne : "(...) lu par une personne conforme HTML processeur, (...) l'utilisation de ' ou de références d'entités personnalisées peut ne pas être prise en charge (...)". - dans la pratique : les navigateurs modernes le supportent même en HTML . Re case in hex nums. (même source ; c'est moi qui souligne) : "Les x doivent être en minuscules dans les documents XML. [ ] Le hhhh peut mélanger les majuscules et les minuscules. la majuscule est le style habituel ." On peut se demander qui a décidé d'encoder les slashs ; peut-être s'agit-il simplement d'une confusion entre l'encodage URI et HTML ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X