Comment utiliser jQuery pour décoder des entités HTML dans une chaîne?
Note de sécurité: l'utilisation de cette réponse (conservée dans sa forme d'origine ci-dessous) peut introduire un vulnérabilité XSS dans votre application. Vous ne devriez pas utiliser cette réponse. Lisez réponse de lucascaro pour une explication des vulnérabilités de cette réponse et utilisez l'approche tirée de cette réponse ou de réponse de Mark Amery .
En fait, essayez
var decoded = $("<div/>").html(encodedStr).text();
Sans jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
Cela fonctionne de la même manière que réponse acceptée , mais son utilisation est sûre avec une entrée utilisateur non fiable.
Comme noté par Mike Samuel _, le faire avec un <div>
au lieu d'un <textarea>
avec une entrée utilisateur non fiable est une vulnérabilité XSS, même si le <div>
n'est jamais ajouté au DOM:
function decodeEntities(encodedString) {
var div = document.createElement('div');
div.innerHTML = encodedString;
return div.textContent;
}
// Shows an alert
decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">')
Toutefois, cette attaque n'est pas possible contre un <textarea>
car aucun élément HTML n'est autorisé dans le contenu d'un <textarea>
. En conséquence, toutes les balises HTML encore présentes dans la chaîne "codée" seront automatiquement codées par entité par le navigateur.
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
// Safe, and returns the correct answer
console.log(decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">'))
Warning: utilisez les méthodes
.html()
et.val()
de jQuery au lieu d'utiliser.innerHTML
et.value
est également non sécurisé * pour certaines versions de jQuery, même en utilisanttextarea
. En effet, les anciennes versions de jQuery auraient évaluent délibérément et explicitement les scripts contenues dans la chaîne transmise à.html()
. Par conséquent, le code comme celui-ci affiche une alerte dans jQuery 1.8:
//<!-- CDATA
// Shows alert
$("<textarea>")
.html("<script>alert(1337);</script>")
.text();
//-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
* Merci à Eru Penkman d'avoir attrapé cette vulnérabilité.
Comme Mike Samuel l'a dit, n'utilisez pas jQuery.html (). Text () pour décoder les entités HTML car il est dangereux.
Au lieu de cela, utilisez un rendu de modèle tel que Mustache.js ou decodeEntities from @ VyvIT.
Underscore.js utility-belt La bibliothèque est fournie avec les méthodes escape
et unescape
, mais elles ne sont pas sécurisées pour les entrées utilisateur:
Je pense que vous confondez le texte et les méthodes HTML. Regardez cet exemple, si vous utilisez le code HTML interne d'un élément comme texte, vous obtiendrez des balises HTML décodées (second bouton). Mais si vous les utilisez en HTML, vous aurez la vue HTML formatée (premier bouton).
<div id="myDiv">
here is a <b>HTML</b> content.
</div>
<br />
<input value="Write as HTML" type="button" onclick="javascript:$('#resultDiv').html($('#myDiv').html());" />
<input value="Write as Text" type="button" onclick="javascript:$('#resultDiv').text($('#myDiv').html());" />
<br /><br />
<div id="resultDiv">
Results here !
</div>
Le premier bouton écrit: voici un contenu HTML.
Le second bouton écrit: voici un contenu <B> HTML </ B>.
A propos, vous pouvez voir un plug-in que j'ai trouvé dans plugin jQuery - HTML décoder et encoder qui encode et décode les chaînes HTML.
La question est limitée par 'avec jQuery', mais il peut être utile de savoir que le code jQuery donné dans la meilleure réponse ci-dessous fait ce qui suit ci-dessous ... cela fonctionne avec ou sans jQuery:
function decodeEntities(input) {
var y = document.createElement('textarea');
y.innerHTML = input;
return y.value;
}
encoder:
$("<textarea/>").html('<a>').html(); // return '<a>'
décoder:
$("<textarea/>").html('<a>').val() // return '<a>'
Vous pouvez utiliser la bibliothèque he _, disponible à partir de https://github.com/mathiasbynens/he
Exemple:
console.log(he.decode("Jörg & Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
J'ai contesté l'auteur de la bibliothèque sur la question de savoir s'il y avait une quelconque raison d'utiliser cette bibliothèque dans le code côté client en faveur du hack <textarea>
fourni dans autres réponses ici et ailleurs. Il a fourni quelques justifications possibles:
Si vous utilisez le fichier node.js, l'utilisation d'une bibliothèque pour le codage/décodage HTML constitue une solution unique qui fonctionne à la fois côté client et côté serveur.
Les algorithmes de décodage d'entités de certains navigateurs présentent des bogues ou ne prennent pas en charge certaines références de caractère name . Par exemple, Internet Explorer décodera et restituera correctement les espaces insécables (
), mais les signalera sous forme d'espaces ordinaires au lieu d'espaces insécables via la propriété innerText
d'un élément DOM, rompant ainsi le hack <textarea>
(bien que de manière mineure). En outre, IE 8 et 9 simplement ne prend pas en charge les nouvelles références de caractères nommés ajoutées dans HTML 5. L'auteur de he organise également un test de prise en charge des références de caractères nommés à http://mathias.html5.org/tests/html/named-character-references/ . Dans IE 8, il rapporte plus de mille erreurs.
Si vous souhaitez vous isoler des bogues de navigateur liés au décodage d'entités et/ou pouvoir gérer l'ensemble des références de caractères nommés, vous ne pouvez pas vous échapper avec le hack <textarea>
; vous aurez besoin d'une bibliothèque comme il.
Il a simplement l'impression de faire les choses de cette façon, c'est moins hacky.
Utilisation
myString = myString.replace( /\&/g, '&' );
Il est plus facile de le faire côté serveur car, apparemment, JavaScript ne possède pas de bibliothèque native pour la gestion des entités, et je n’en ai trouvé aucune en tête des résultats de recherche pour les divers cadres qui étendent JavaScript.
Recherchez "entités HTML JavaScript" et vous trouverez peut-être quelques bibliothèques à cette fin, mais elles seront probablement toutes construites autour de la logique ci-dessus - remplacer, entité par entité.
Vous devez créer une fonction personnalisée pour les entités html:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}
Il me suffisait d'avoir un caractère HTML (⇓) comme valeur pour un bouton HTML. Le code HTML semble bon depuis le début dans le navigateur:
<input type="button" value="Embed & Share ⇓" id="share_button" />
J'ajoutais maintenant une bascule qui devrait également afficher le caractère. C'est ma solution
$("#share_button").toggle(
function(){
$("#share").slideDown();
$(this).attr("value", "Embed & Share " + $("<div>").html("⇑").text());
}
Ceci affiche à nouveau dans le bouton. J'espère que cela pourrait aider quelqu'un.
Alternativement, il y a aussi une bibliothèque pour cela.
ici, https://cdnjs.com/libraries/he
npm install he //using node.js
<script src="js/he.js"></script> //or from your javascript directory
L'utilisation est comme suit ...
//to encode text
he.encode('© Ande & Nonso® Company LImited 2018');
//to decode the
he.decode('© Ande & Nonso® Company Limited 2018');
à votre santé.
Voici encore un problème: La chaîne échappée ne semble pas lisible lorsqu'elle est affectée à la valeur d'entrée
var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);
Exemple: https://jsfiddle.net/kjpdwmqa/3/
Étendre une classe de chaîne:
String::decode = ->
$('<textarea />').html(this).text()
et utiliser comme méthode:
"<img src='myimage.jpg'>".decode()
Essaye ça :
var htmlEntities = "<script>alert('hello');</script>";
var htmlDecode =$.parseHTML(htmlEntities)[0]['wholeText'];
console.log(htmlDecode);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
parseHTML est une fonction de la bibliothèque Jquery qui retournera un tableau contenant des détails sur la chaîne donnée.
dans certains cas, la chaîne est grande, la fonction séparera donc le contenu en plusieurs index.
et pour obtenir toutes les données d'index, vous devez accéder à n'importe quel index, puis accéder à l'index appelé "wholeText".
J'ai choisi l'index 0 car cela fonctionnera dans tous les cas (petite chaîne ou grande chaîne).
Pour les utilisateurs d'ExtJS, si vous avez déjà la chaîne codée, par exemple lorsque la valeur renvoyée d'une fonction de bibliothèque est le contenu innerHTML, considérez cette fonction ExtJS:
Ext.util.Format.htmlDecode(innerHtmlContent)
Supposons que vous ayez en dessous de String.
Nos cabines Deluxe sont chaleureuses et confortables. confortable
var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text(); // Now,decode html entities in your variable i.e
str et assigner à
étiquette.
c'est tout.