J'ai du code Javascript qui communique avec un backend XML-RPC. Le XML-RPC renvoie des chaînes de la forme:
<img src='myimage.jpg'>
Cependant, lorsque j'utilise le Javascript pour insérer les chaînes dans HTML, elles sont rendues littéralement. Je ne vois pas d'image, je vois littéralement la chaîne:
<img src='myimage.jpg'>
Je suppose que le HTML est échappé via le canal XML-RPC.
Comment puis-je échapper à la chaîne en Javascript? J'ai essayé les techniques de cette page, sans succès: http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/
Quels sont les autres moyens de diagnostiquer le problème?
javascript
html
escaping
xml-rpc
Joseph Turian
la source
la source
Réponses:
EDIT: Vous devriez utiliser l'API DOMParser comme le suggère Wladimir , j'ai édité ma réponse précédente car la fonction publiée a introduit une faille de sécurité.
L'extrait suivant est l'ancien code de la réponse avec une petite modification: l'utilisation de a
textarea
au lieu de adiv
réduit la vulnérabilité XSS, mais elle est toujours problématique dans IE9 et Firefox.Fondamentalement, je crée un élément DOM par programme, assigne le HTML encodé à son innerHTML et récupère le nodeValue à partir du nœud de texte créé lors de l'insertion innerHTML. Puisqu'il crée simplement un élément mais ne l'ajoute jamais, aucun code HTML de site n'est modifié.
Il fonctionnera sur plusieurs navigateurs (y compris les anciens navigateurs) et acceptera toutes les entités de caractères HTML .
EDIT: L'ancienne version de ce code ne fonctionnait pas sur IE avec des entrées vides, comme en témoigne ici jsFiddle (vue dans IE). La version ci-dessus fonctionne avec toutes les entrées.
MISE À JOUR: semble que cela ne fonctionne pas avec une grande chaîne, et cela introduit également une vulnérabilité de sécurité , voir les commentaires.
la source
'
n'appartient pas aux entités HTML 4, c'est pourquoi! w3.org/TR/html4/sgml/entities.html fishbowl.pastiche.org/2003/07/01/the_curse_of_aposLa plupart des réponses données ici ont un énorme inconvénient: si la chaîne que vous essayez de convertir n'est pas fiable, vous vous retrouverez avec une vulnérabilité de Cross-Site Scripting (XSS) . Pour la fonction dans la réponse acceptée, tenez compte de ce qui suit:
La chaîne ici contient une balise HTML sans échappement, donc au lieu de décoder quoi que ce soit, la
htmlDecode
fonction exécutera en fait le code JavaScript spécifié dans la chaîne.Cela peut être évité en utilisant DOMParser qui est pris en charge dans tous les navigateurs modernes :
Il est garanti que cette fonction n'exécute aucun code JavaScript comme effet secondaire. Toutes les balises HTML seront ignorées, seul le contenu textuel sera renvoyé.
Note de compatibilité : L'analyse HTML avec
DOMParser
nécessite au moins Chrome 30, Firefox 12, Opera 17, Internet Explorer 10, Safari 7.1 ou Microsoft Edge. Ainsi, tous les navigateurs sans support ont bien dépassé leur fin de vie et à partir de 2017, les seuls qui peuvent encore être vus dans la nature sont les anciennes versions d'Internet Explorer et de Safari (généralement, elles ne sont toujours pas assez nombreuses pour déranger).la source
DOMParser
ne prenait pas en charge"text/html"
avant Firefox 12.0, et il existe encore certaines dernières versions de navigateurs qui ne prennent même pas en chargeDOMParser.prototype.parseFromString()
. Selon votre référence, ilDOMParser
s'agit toujours d'une technologie expérimentale, et les remplaçants utilisent lainnerHTML
propriété qui, comme vous l'avez également souligné en réponse à mon approche , présente cette vulnérabilité XSS (qui devrait être corrigée par les fournisseurs de navigateurs).<script>
balises non exécutées ne sont pas un mécanisme de sécurité, cette règle évite simplement les problèmes de synchronisation délicats si le paramétrageinnerHTML
pouvait exécuter des scripts synchrones en tant qu'effet secondaire. La désinfection du code HTML est une affaire délicate etinnerHTML
n'essaye même pas - déjà parce que la page Web pourrait en fait avoir l'intention de définir des gestionnaires d'événements en ligne. Ce n'est tout simplement pas un mécanisme destiné aux données dangereuses, point final.Si vous utilisez jQuery:
Sinon, utilisez l'objet Encoder de Strictly Software , qui a une excellente
htmlDecode()
fonction.la source
L'astuce consiste à utiliser la puissance du navigateur pour décoder les caractères HTML spéciaux, mais pas à permettre au navigateur d'exécuter les résultats comme s'il s'agissait de véritables html ... Cette fonction utilise une expression régulière pour identifier et remplacer les caractères HTML encodés, un caractère à la fois.
la source
/\&#?[0-9a-z]+;/gi
puisque # ne devrait apparaître que comme le deuxième caractère, voire pas du tout.La réponse de CMS fonctionne bien, à moins que le code HTML que vous voulez ne pas échapper soit très long, plus de 65 536 caractères. Parce que dans Chrome, le HTML interne est divisé en plusieurs nœuds enfants, chacun d'au plus 65536 de long, et vous devez les concaténer. Cette fonction fonctionne également pour les très longues chaînes:
Voir cette réponse sur
innerHTML
la longueur maximale pour plus d'informations: https://stackoverflow.com/a/27545633/694469la source
Pas une réponse directe à votre question, mais ne serait-il pas préférable que votre RPC renvoie une structure (que ce soit XML ou JSON ou autre) avec ces données d'image (URL dans votre exemple) à l'intérieur de cette structure?
Ensuite, vous pouvez simplement l'analyser dans votre javascript et créer le
<img>
javascript lui-même.La structure que vous recevez de RPC pourrait ressembler à:
Je pense que c'est mieux ainsi, car l'injection d'un code provenant d'une source externe dans votre page ne semble pas très sécurisée. Créer une image de quelqu'un qui pirate votre script XML-RPC et y mettre quelque chose que vous ne voudriez pas (même du javascript ...)
la source
htmlDecode("<img src='myimage.jpg'><script>alert('xxxxx');</script>")
et rien ne s'est passé. J'ai récupéré la chaîne html décodée comme prévu.La réponse de Chris est belle et élégante mais elle échoue si la valeur n'est pas définie . Une simple amélioration le rend solide:
la source
return (typeof value !== 'string') ? '' : $('<div/>').html(value).text();
Vous êtes le bienvenu ... juste un messager ... tout le mérite revient à ourcodeworld.com, lien ci-dessous.
Crédit complet: https://ourcodeworld.com/articles/read/188/encode-and-decode-html-entities-using-pure-javascript
la source
C'est la solution la plus complète que j'ai essayée jusqu'à présent:
la source
J'étais assez fou pour passer en revue et faire cette fonction qui devrait être jolie, sinon complètement, exhaustive:
Utilisé comme ça:
Impressions:
Ich Heiße David
PS cela a pris environ une heure et demie à faire.
la source
Pour échapper aux entités HTML * en JavaScript, vous pouvez utiliser la petite bibliothèque html-escaper :
npm install html-escaper
Ou
unescape
fonction de Lodash ou Underscore , si vous l'utilisez.*) S'il vous plaît noter que ces fonctions ne couvrent pas toutes les entités HTML, mais seulement, à savoir les plus communs
&
,<
,>
,'
,"
. Pour Unescape toutes les entités HTML , vous pouvez utiliser il bibliothèque.la source
J'utilise ceci dans mon projet: inspiré par d' autres réponses mais avec un paramètre supplémentaire sécurisé, peut être utile lorsque vous traitez avec des personnages décorés
Et c'est utilisable comme:
la source
Toutes les autres réponses ici ont des problèmes.
Les méthodes document.createElement ('div') (y compris celles utilisant jQuery) exécutent tout javascript qui y est passé (un problème de sécurité) et la méthode DOMParser.parseFromString () supprime les espaces. Voici une solution javascript pure qui n'a aucun problème:
TextArea est utilisé spécifiquement pour éviter d'exécuter le code js. Il passe ceux-ci:
la source
htmlDecode("</textarea><img src=x onerror=alert(1)>")
. Vous avez posté ceci après avoir déjà signalé ce problème sur la réponse de Sergio Belevskij.la source
Il existe une variante 80% aussi productive que les réponses tout en haut.
Voir le benchmark: https://jsperf.com/decode-html12345678/1
Si vous devez laisser des balises, supprimez les deux
.replace(...)
appels (vous pouvez laisser le premier si vous n'avez pas besoin de scripts).la source
decodeEntities("</textarea '><img src=x onerror=alert(1) \">")
dans Firefox. Veuillez arrêter d'essayer de nettoyer le code HTML avec des expressions régulières.