Comment coder et décoder des entités HTML en utilisant JavaScript ou JQuery ?
var varTitle = "Chris' corner";
Je veux que ça le soit :
var varTitle = "Chris' corner";
Comment coder et décoder des entités HTML en utilisant JavaScript ou JQuery ?
var varTitle = "Chris' corner";
Je veux que ça le soit :
var varTitle = "Chris' corner";
Je vous déconseille d'utiliser le code jQuery qui a été accepté comme réponse. Bien qu'il n'insère pas la chaîne à décoder dans la page, il entraîne la création d'éléments tels que des scripts et des éléments HTML. C'est beaucoup plus de code que ce dont nous avons besoin. Je suggère plutôt d'utiliser une fonction plus sûre et plus optimisée.
var decodeEntities = (function() {
// this prevents any overhead from creating the object each time
var element = document.createElement('div');
function decodeHTMLEntities (str) {
if(str && typeof str === 'string') {
// strip script/html tags
str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
element.innerHTML = str;
str = element.textContent;
element.textContent = '';
}
return str;
}
return decodeHTMLEntities;
})();
Pour utiliser cette fonction, il suffit d'appeler decodeEntities("&")
et il utilisera les mêmes techniques sous-jacentes que la version jQuery, mais sans la surcharge de jQuery, et après avoir nettoyé les balises HTML dans l'entrée. Voir Commentaire de Mike Samuel sur la réponse acceptée pour savoir comment filtrer les balises HTML.
Cette fonction peut être facilement utilisée comme un plugin jQuery en ajoutant la ligne suivante dans votre projet.
jQuery.decodeEntities = decodeEntities;
Quelqu'un peut-il me dire ce que str.replace(/<\/ ? \w (? :[^"'>]|"[^"]*"|'[^']*')*>/gmi, '') ; does ?
Remarque : textContent n'est pas pris en charge dans IE8, donc si c'est toujours l'un de vos navigateurs cibles, vous devez trouver une autre solution. Je viens de perdre une heure à essayer de comprendre cela, puisque nous devons décoder les entités spécifiquement pour compenser un autre bug d'IE8.
Vous pourriez essayer quelque chose comme :
var Title = $('<textarea />').html("Chris' corner").text();
console.log(Title);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Une version plus interactive :
$('form').submit(function() {
var theString = $('#string').val();
var varTitle = $('<textarea />').html(theString).text();
$('#output').text(varTitle);
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post">
<fieldset>
<label for="string">Enter a html-encoded string to decode</label>
<input type="text" name="string" id="string" />
</fieldset>
<fieldset>
<input type="submit" value="decode" />
</fieldset>
</form>
<div id="output"></div>
Cool, ça marche. Par curiosité, le $('div />') est utilisé pour créer un élément <div> autour du varTitle ?
@chris et @david - Ce code crée un div vide (détaché du DOM) et définit son innerHTML, puis le récupère en tant que texte normal. Ce n'est pas en l'entourant d'un DIV mais le mettre dans un div . J'insiste sur ce point car il est essentiel de comprendre le fonctionnement de jQuery.
Ne l'utilisez PAS avec des données non fiables, voir le commentaire de Mike ici : stackoverflow.com/questions/1147359/
Comme l'a dit Robert K, n'utilisez pas jQuery.html().text() pour décoder les entités html, car cela n'est pas sûr, l'entrée utilisateur ne devant jamais avoir accès au DOM. Lire à ce sujet XSS pour expliquer pourquoi ce n'est pas sûr.
Essayez plutôt le Underscore.js la bibliothèque de courroies utilitaires qui est fournie avec s'échapper y s'évader méthodes :
Échappe une chaîne de caractères pour l'insérer dans le HTML, en remplaçant &
, <
, >
, "
, `
y '
des personnages.
_.escape('Curly, Larry & Moe');
=> "Curly, Larry & Moe"
Le contraire de l'évasion, remplace &
, <
, >
, "
, `
y '
avec leurs équivalents non encodés.
_.unescape('Curly, Larry & Moe');
=> "Curly, Larry & Moe"
Pour prendre en charge le décodage d'un plus grand nombre de caractères, il suffit de copier l'Underscore s'évader et ajouter d'autres personnages à la carte.
@chovy, utilisez la dernière version de Underscore.js >= 1.4.2 et vous n'obtiendrez pas de TypeError.
C'est en gros la seule chose qui fonctionne pour moi. J'ai besoin de trouver les balises script contenant des modèles, puis de les parcourir pour trouver les sous-sections de ces modèles. En faisant cela avec jQuery, jQ convertit tout le html "invalide" (aka les balises de modèle) en entités. Pour récupérer les sous-sections, il faut les désencapsuler à nouveau, et pour cela, aucune des autres réponses ne fonctionne.
Voici une méthode rapide qui ne nécessite pas la création d'un div et qui décode les caractères échappés HTML les plus courants :
function decodeHTMLEntities(text) {
var entities = [
['amp', '&'],
['apos', '\''],
['#x27', '\''],
['#x2F', '/'],
['#39', '\''],
['#47', '/'],
['lt', '<'],
['gt', '>'],
['nbsp', ' '],
['quot', '"']
];
for (var i = 0, max = entities.length; i < max; ++i)
text = text.replace(new RegExp('&'+entities[i][0]+';', 'g'), entities[i][1]);
return text;
}
Votre réponse ne fonctionne pas du tout pour la plupart des entités html, et l'étendre pour les inclure serait plutôt répétitif et source d'erreurs. Par exemple, il existe une entité pour chaque caractère japonais kanji, qui se compte par milliers. De plus, à ce stade, je ne serais pas surpris que votre réponse soit plus lente que certaines des autres ici, puisque vous auriez à exécuter des milliers de replaces avec des milliers de regex pour chaque chaîne à décoder.
Cela dépend vraiment du BUT que vous poursuivez en encodant ces chaînes de caractères. Si votre objectif est de ne pas déclencher de traitement HTML via des éléments tels que < ou >, il n'est absolument pas nécessaire d'encoder les autres caractères via la syntaxe des entités de caractères. La grande quantité d'entités de caractères sert principalement d'outil pratique. Les entités que j'ai énumérées sont le strict minimum de celles auxquelles vous devez échapper pour éviter que les données soient mélangées avec le HTML. [Suite dans le commentaire suivant]
Pour ce qui est de la rapidité, il est bon d'avoir exécuté plusieurs regex. Mais bien sûr, puisque votre idée de mettre chaque entité de caractère dans ce code est inutile et franchement, vraiment stupide, ce n'est pas un problème. On pourrait cependant générer la regex en utilisant d'abord le caractère | et faire un seul appel à replace(). Je pense qu'il faudrait faire un test pour voir ce qui est le plus rapide, mais mon intuition me dit que ce sera plus rapide d'utiliser | avec un seul replace() en raison de la surcharge des appels de fonction qui est élevée en Javascript.
Inspirée de la solution de Robert K, cette version ne supprime pas les balises HTML et est tout aussi sûre.
var decode_entities = (function() {
// Remove HTML Entities
var element = document.createElement('div');
function decode_HTML_entities (str) {
if(str && typeof str === 'string') {
// Escape HTML before decoding for HTML Entities
str = escape(str).replace(/%26/g,'&').replace(/%23/g,'#').replace(/%3B/g,';');
element.innerHTML = str;
if(element.innerText){
str = element.innerText;
element.innerText = '';
}else{
// Firefox support
str = element.textContent;
element.textContent = '';
}
}
return unescape(str);
}
return decode_HTML_entities;
})();
Ces escape()
y unescape()
sont dépréciées. developer.mozilla.org/fr/US/docs/Web/JavaScript/Référence/
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.
16 votes
Voir cette réponse . Semble meilleur que ce qui est proposé ci-dessous.
1 votes
Voir aussi le module ent (sur npm !) github.com/substack/node-ent
1 votes
Je pense que @ringø (wow, nom d'utilisateur étrangement similaire...) voulait faire un lien vers cette réponse
2 votes
@rinogo Je pensais c'était la meilleure réponse . apparemment le il lib est conçu exactement dans ce but. Vous pourriez être en mesure d'économiser quelques lignes de code avec une implémentation personnalisée comme la plupart des réponses ici, mais ils ont tous des limitations d'une manière ou d'une autre.
0 votes
Une manière plus concise : stackoverflow.com/a/64587244/9854149