Question Echapper aux chaînes HTML avec jQuery


Est-ce que quelqu'un sait d'un moyen facile d'échapper à HTML à partir de chaînes dans jQuery? Je dois être en mesure de passer une chaîne arbitraire et l'avoir correctement échappé pour l'affichage dans une page HTML (empêchant les attaques par injection JavaScript / HTML). Je suis sûr qu'il est possible d'étendre jQuery pour ce faire, mais je ne connais pas assez le framework pour le moment.


547
2017-08-24 02:52


origine


Réponses:


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;

391
2017-08-24 17:22



Il y a aussi la solution de moustache.js

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

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

530
2017-08-20 08:21



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

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


177
2017-12-17 10:28



Si vous vous échappez pour le HTML, il n'y en a que trois que je puisse penser qui seraient vraiment nécessaires:

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

Selon votre cas d'utilisation, vous devrez peut-être également faire des choses comme " à &quot;. Si la liste devenait 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.


57
2017-08-24 05:54



J'ai écrit une toute petite fonction qui fait cela. Il échappe seulement ", &, < et > (mais généralement c'est tout ce dont vous avez besoin de toute façon). Il est légèrement plus élégant que les solutions proposées précédemment en ce sens qu'il n'utilise que un  .replace() faire toute la conversion. (EDIT 2: Réduction de la complexité du code rendant la fonction encore plus petite et plus claire, si vous êtes curieux du 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];
    });
}

C'est Javascript simple, pas de jQuery utilisé.

S'échapper / et ' aussi

Modifier en réponse à mklementle 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 dans la classe de caractères dans l'expression régulière (c'est-à-dire dans le /[...]/g) et en tant qu'entrée dans le chr objet. (EDIT 2: Raccourci aussi 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 l'apostrophe (l'entité symbolique &apos; a peut-être été utilisé à la place - il est défini en XML, mais n'était à l'origine pas inclus dans la spécification HTML et pourrait donc ne pas être supporté par tous les navigateurs. Voir: Article Wikipedia sur les encodages de caractères HTML). Je me souviens aussi d'avoir lu quelque part que l'utilisation d'entités décimales est plus largement supportée que l'utilisation d'hexadécimal, mais je n'arrive pas à trouver la source pour ça maintenant. (Et il ne peut y avoir beaucoup de navigateurs qui ne supportent pas les entités hexadécimales.)

Remarque: Ajouter / et ' à la liste des caractères échappés n'est pas très utile, car ils n'ont pas de signification particulière en HTML et ne avoir besoin être échappé.

Original escapeHtml Fonction

EDIT 2: La fonction d'origine utilisait une variable (chr) pour stocker l'objet nécessaire à la .replace() rappeler. Cette variable a également besoin d'une fonction anonyme supplémentaire pour la définir, rendant 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.


35
2017-11-14 00:39



Assez facile à utiliser le soulignement:

_.escape(string) 

Souligner est une bibliothèque utilitaire qui fournit beaucoup de fonctionnalités que js natif ne fournit pas. Il y a aussi lodash qui est la même API que le soulignement, mais a été réécrit pour être plus performant.


31
2017-09-12 05:30



Je me rends compte à quelle heure je suis à cette fête, mais j'ai une solution très simple qui ne nécessite pas jQuery.

escaped = new Option(unescaped).innerHTML;

Edit: Cela n'échappe pas aux citations. Le seul cas où les guillemets devraient être échappés est si le contenu va être collé en ligne à un attribut dans une chaîne HTML. Il m'est difficile d'imaginer un cas où ce serait un bon design.

Edit 2: Si la performance est cruciale, la solution la plus performante (d'environ 50%) est encore une série de remplacements d'expressions rationnelles. Les navigateurs modernes détecteront que les expressions régulières ne contiennent aucun opérateur, juste une chaîne, et les réduiront en une seule opération.


29
2018-03-01 22:55



Voici une fonction JavaScript propre et claire. Il s'échappera du texte tel que «quelques <nombreux» dans «quelques-uns».

function escapeHtmlEntities (str) {
  if (typeof jQuery !== 'undefined') {
    // Create an empty div to use as a container,
    // then put the raw text in and get the HTML
    // equivalent out.
    return jQuery('<div/>').text(str).html();
  }

  // No jQuery, so use string replace.
  return str
    .replace(/&/g, '&amp;')
    .replace(/>/g, '&gt;')
    .replace(/</g, '&lt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&apos;');
}

26
2018-05-30 23:46



Essayer Underscore.string lib, cela fonctionne avec jQuery.

_.str.escapeHTML('<div>Blah blah blah</div>')

sortie:

'&lt;div&gt;Blah blah blah&lt;/div&gt;'

24
2017-08-20 07:36



Après les derniers tests, je peux recommander le plus rapide et complètement navigateur croisé compatible javaScript natif (DOM) solution:

function HTMLescape(html){
    return document.createElement('div')
        .appendChild(document.createTextNode(html))
        .parentNode
        .innerHTML
}

Si vous le répétez plusieurs fois, vous pouvez le faire avec des variables une fois préparées:

//prepare variables
var DOMtext = document.createTextNode("test");
var DOMnative = document.createElement("span");
DOMnative.appendChild(DOMtext);

//main work for each case
function HTMLescape(html){
  DOMtext.nodeValue = html;
  return DOMnative.innerHTML
}

Regardez ma dernière performance Comparaison (poser une question).


23
2017-07-09 10:44