247 votes

Comment supprimer les balises HTML d'une chaîne en JavaScript?

Comment puis-je supprimer le HTML d'une chaîne en JavaScript ?

384voto

ReactiveRaven Points 729
cleanText = strInputCode.replace(/<\/?[^>]+(>|$)/g, "");

Extrait de ce site web (web.archive).

Cette expression régulière recherche <, un slash optionnel /, un ou plusieurs caractères qui ne sont pas >, puis soit > soit $ (la fin de la ligne)

Exemples:

'Bonjour' ==> 'Bonjour'
 ^^^^^     ^^^^^^
'Balise non terminée  'Balise non terminée '
                  ^^

Mais ce n'est pas infaillible:

'Si vous avez < 13 ans vous ne pouvez pas vous inscrire' ==> 'Si vous avez '
            ^^^^^^^^^^^^^^^^^^^^^^
'Bonjour' ==> ' 42">Bonjour'
 ^^^^^^^^^^^^^^^^^^          ^^^^^^

Si quelqu'un essaie de saboter votre application, cette expression régulière ne vous protégera pas. Elle ne doit être utilisée que si vous connaissez déjà le format de votre entrée. Comme l'ont souligné d'autres personnes compétentes et pour la plupart saines d'esprit, pour supprimer les balises en toute sécurité, vous devez utiliser un analyseur.

Si vous n'avez pas accès à un analyseur pratique comme le DOM, et que vous ne pouvez pas faire confiance à votre entrée pour être dans le bon format, vous feriez mieux d'utiliser un package comme sanitize-html, et aussi d'autres sanitizers sont disponibles.

35 votes

Désolé, mais cela casserait ![a>b](a_b.gif)

125 votes

@f.ardelian les personnes qui font un passe-temps de casser l'utilisation abusive des expressions régulières pour l'analyse générale du HTML sont formidables. C'est un excellent passe-temps.

3 votes

@Ziggy: Cela ressemble étrangement à du sarcasme...

285voto

Tim Down Points 124501

Utiliser l'analyseur du navigateur est probablement le meilleur choix dans les navigateurs actuels. Ce qui suit fonctionnera, avec les réserves suivantes:

  • Votre HTML est valide à l'intérieur d'un élément

    . Le HTML contenu dans les balises ou ou n'est pas valide à l'intérieur d'un

    et peut donc ne pas être analysé correctement.

  • textContent (la propriété standard du DOM) et les propriétés innerText (non standard) ne sont pas identiques. Par exemple, textContent inclura le texte à l'intérieur d'un élément </code> alors que <code>innerText</code> ne le fera pas (dans la plupart des navigateurs). Cela n'affecte que IE <=8, qui est le seul navigateur majeur à ne pas supporter <code>textContent</code>.</li> <li>Le HTML ne contient pas d'éléments <code><script></code>.</li> <li>Le HTML n'est pas <code>null</code></li> <li>Le HTML provient d'une source de confiance. L'utilisation de ceci avec du HTML arbitraire permet l'exécution de JavaScript arbitraire non fiable. Cet exemple provient d'un commentaire de Mike Samuel sur la question dupliquée : <code><img onerror='alert(\"could run arbitrary JS here\")' src=bogus></code></li> </ul> <p>Code:</p> <pre><code>var html = "<p>Some HTML</p>"; var div = document.createElement("div"); div.innerHTML = html; var text = div.textContent || div.innerText || ""; </code></pre></x-turndown>

0 votes

Belle réponse, je ne connaissais pas textContent. Combien de navigateurs prennent en charge textContent + innerText ? Au fait, j'ai modifié ma réponse pour inclure la manière jQuery.

0 votes

@Felix: Tous les principaux navigateurs ont au moins l'un des textContent et innerText.

5 votes

Ne fonctionne pas lorsque la chaîne contient quelque chose comme alert('salut');. Ensuite, cela plante avec "jeton illégal à" etc..

72voto

Felix Points 33944
var html = "

C'est à peu près la meilleure façon de le faire, vous laissez le navigateur faire ce qu'il fait le mieux - analyser le HTML.


Édit: Comme indiqué dans les commentaires ci-dessous, ce n'est pas la solution la plus compatible avec tous les navigateurs. La solution la plus compatible avec tous les navigateurs serait de parcourir de manière récursive tous les enfants de l'élément et de concaténer tous les nœuds texte que vous trouvez. Cependant, si vous utilisez jQuery, il le fait déjà pour vous:

alert($("Bonjour, Monde").text());

Jetez un œil à la méthode text.

3 votes

Tous les navigateurs ne prennent pas en charge innerText.

9 votes

Un jQuery concis pourrait ressembler à: var html = "**test**"; var text = $("

").html(html).text(); L'utilisation de $("

") vous permet de réutiliser le même élément et de consommer moins de mémoire pour les appels consécutifs ou les boucles.

2 votes

Même problème, écrasez-le avec : $(...).html('alert("hi");').text();

32voto

Till Points 14673

Je sais que cette question a une réponse acceptée, mais je sens que cela ne fonctionne pas dans tous les cas.

Pour la complétude et puisque j'ai passé trop de temps sur cela, voici ce que nous avons fait : nous avons fini par utiliser une fonction de php.js (qui est une bibliothèque assez sympa pour ceux qui sont plus familiers avec PHP mais font aussi un peu de JavaScript de temps en temps) :

http://phpjs.org/functions/strip_tags:535

Cela semblait être le seul morceau de code JavaScript qui traitait avec succès tous les différents types d'entrées que j'ai ajoutés à mon application. C'est-à-dire sans le casser - voyez mes commentaires sur la balise </code> ci-dessus.</p></x-turndown>

2 votes

^ ceci, certainement meilleur que la réponse acceptée pour Chrome 30.0 et supérieur

0 votes

Fonctionne bien côté serveur sans support DOM, par exemple Google Apps Script.

1 votes

Si vous utilisez le paramètre autorisé, vous êtes vulnérable à XSS: `stripTags('

mon texte

', '`

') renvoie

mon texte

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