J'ai des ficelles comme
var str = 'One & two & three';
rendu en HTML par le serveur Web. J'ai besoin de transformer ces cordes en
'One & two & three'
Actuellement, c'est ce que je fais (avec l'aide de jQuery):
$(document.createElement('div')).html('{{ driver.person.name }}').text()
Cependant, j'ai le sentiment troublant que je me trompe. j'ai essayé
unescape("&")
mais cela ne semble pas fonctionner, ni decodeURI/decodeURIComponent.
Y a-t-il d'autres façons plus indigènes et élégantes de le faire?
Une option plus moderne pour interpréter le code HTML (texte ou autre) à partir de JavaScript est le support HTML dans l'API DOMParser
( voir ici dans MDN ). Cela vous permet d'utiliser l'analyseur HTML natif du navigateur pour convertir une chaîne en un document HTML. Il est pris en charge dans les nouvelles versions de tous les principaux navigateurs depuis fin 2014.
Si nous voulons simplement décoder du contenu textuel, nous pouvons le placer comme contenu unique dans un corps de document, analyser le document et extraire le son .body.textContent
.
var encodedStr = 'hello & world';
var parser = new DOMParser;
var dom = parser.parseFromString(
'<!doctype html><body>' + encodedStr,
'text/html');
var decodedString = dom.body.textContent;
console.log(decodedString);
Nous pouvons voir dans spécification préliminaire pour DOMParser
que JavaScript n'est pas activé pour le document analysé, ce qui nous permet d'effectuer cette conversion de texte sans souci de sécurité.
La méthode
parseFromString(str, type)
doit exécuter ces étapes en fonction du type :
"text/html"
Analyse str avec un
HTML parser
et renvoie leDocument
nouvellement créé.L'indicateur de script doit être défini sur "désactivé".
REMARQUELes éléments
script
sont marqués comme non exécutables et le contenu denoscript
est analysé comme un balisage.
Cela dépasse le cadre de cette question, mais , veuillez noter que si vous prenez les nœuds DOM analysés eux-mêmes (pas uniquement leur contenu texte) et les déplacez dans le document en direct DOM, il est possible que leur script soit réactivé et que des problèmes de sécurité se posent. Je n'ai pas fait de recherches, alors faites preuve de prudence.
Avez-vous besoin de décoder toutes les entités HTML encodées ou simplement &
lui-même?
Si vous avez seulement besoin de gérer &
, alors vous pouvez le faire:
var decoded = encoded.replace(/&/g, '&');
Si vous devez décoder toutes les entités HTML, vous pouvez le faire sans jQuery:
var elem = document.createElement('textarea');
elem.innerHTML = encoded;
var decoded = elem.value;
Veuillez prendre note des commentaires de Mark ci-dessous qui soulignent les failles de sécurité dans une version antérieure de cette réponse et vous recommandons d'utiliser textarea
plutôt que div
pour atténuer les vulnérabilités XSS potentielles. Ces vulnérabilités existent que vous utilisiez ou non jQuery ou JavaScript simple.
Matthias Bynens a une bibliothèque pour cela: 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"
Je suggère de le privilégier par rapport aux hacks impliquant la définition du contenu HTML d'un élément, puis la lecture de son contenu textuel. De telles approches peuvent fonctionner, mais sont faussement dangereuses et représentent des opportunités XSS si elles sont utilisées avec une entrée utilisateur non fiable.
Si vous ne pouvez vraiment pas supporter de charger dans une bibliothèque, vous pouvez utiliser le hack textarea
décrit dans cette réponse à une question presque en double, qui, contrairement à diverses approches similaires qui ont déjà été utilisées. suggéré, n'a pas de faille de sécurité que je sache:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
Mais prenez note des problèmes de sécurité affectant des approches similaires à celles-ci, que je mentionne dans la réponse associée! Cette approche est un hack, et les modifications futures du contenu autorisé d'un textarea
(ou de bogues dans certains navigateurs) pourraient conduire à un code qui repose sur le fait qu'il subit soudainement un trou XSS.
var htmlEnDeCode = (function() {
var charToEntityRegex,
entityToCharRegex,
charToEntity,
entityToChar;
function resetCharacterEntities() {
charToEntity = {};
entityToChar = {};
// add the default set
addCharacterEntities({
'&' : '&',
'>' : '>',
'<' : '<',
'"' : '"',
''' : "'"
});
}
function addCharacterEntities(newEntities) {
var charKeys = [],
entityKeys = [],
key, echar;
for (key in newEntities) {
echar = newEntities[key];
entityToChar[key] = echar;
charToEntity[echar] = key;
charKeys.Push(echar);
entityKeys.Push(key);
}
charToEntityRegex = new RegExp('(' + charKeys.join('|') + ')', 'g');
entityToCharRegex = new RegExp('(' + entityKeys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');
}
function htmlEncode(value){
var htmlEncodeReplaceFn = function(match, capture) {
return charToEntity[capture];
};
return (!value) ? value : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn);
}
function htmlDecode(value) {
var htmlDecodeReplaceFn = function(match, capture) {
return (capture in entityToChar) ? entityToChar[capture] : String.fromCharCode(parseInt(capture.substr(2), 10));
};
return (!value) ? value : String(value).replace(entityToCharRegex, htmlDecodeReplaceFn);
}
resetCharacterEntities();
return {
htmlEncode: htmlEncode,
htmlDecode: htmlDecode
};
})();
Cela provient du code source ExtJS.
element.innerText
fait aussi l'affaire.
Si vous le recherchez, comme moi, il existe une méthode JQuery agréable et sûre.
https://api.jquery.com/jquery.parsehtml/
Vous pouvez f.ex. tapez ceci dans votre console:
var x = "test &";
> undefined
$.parseHTML(x)[0].textContent
> "test &"
Donc, $ .parseHTML (x) renvoie un tableau et si vous avez du balisage HTML dans votre texte, le tableau.length sera supérieur à 1.
Vous pouvez utiliser la fonction Lodash unescape/escape https://lodash.com/docs/4.17.5#unescape
import unescape from 'lodash/unescape';
const str = unescape('fred, barney, & pebbles');
str deviendra 'fred, barney, & pebbles'
jQuery va encoder et décoder pour vous. Cependant, vous devez utiliser une balise textarea, pas une div.
var str1 = 'One & two & three';
var str2 = "One & two & three";
$(document).ready(function() {
$("#encoded").text(htmlEncode(str1));
$("#decoded").text(htmlDecode(str2));
});
function htmlDecode(value) {
return $("<textarea/>").html(value).text();
}
function htmlEncode(value) {
return $('<textarea/>').text(value).html();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="encoded"></div>
<div id="decoded"></div>
Commencez par créer un <span id="decodeIt" style="display:none;"></span>
quelque part dans le corps.
Ensuite, assignez la chaîne à décoder en tant que innerHTML à ceci:
document.getElementById("decodeIt").innerHTML=stringtodecode
Finalement,
stringtodecode=document.getElementById("decodeIt").innerText
Voici le code général:
var stringtodecode="<B>Hello</B> world<br>";
document.getElementById("decodeIt").innerHTML=stringtodecode;
stringtodecode=document.getElementById("decodeIt").innerText
Pour les gars d'une ligne:
const htmlDecode = innerHTML => Object.assign(document.createElement('textarea'), {innerHTML}).value;
console.log(htmlDecode('Complicated - Dimitri Vegas & Like Mike'));
une solution javascript qui capture les plus communs:
var map = {amp: '&', lt: '<', gt: '>', quot: '"', '#039': "'"}
str = str.replace(/&([^;]+);/g, (m, c) => map[c])
c'est l'inverse de https://stackoverflow.com/a/4835406/2738039
J'ai tout essayé pour supprimer et d'un tableau JSON. Aucun des exemples ci-dessus, mais https://stackoverflow.com/users/2030321/chris a donné une excellente solution qui m'a amené à résoudre mon problème.
var stringtodecode="<B>Hello</B> world<br>";
document.getElementById("decodeIt").innerHTML=stringtodecode;
stringtodecode=document.getElementById("decodeIt").innerText
Je ne l'ai pas utilisé, car je ne savais pas comment l'insérer dans une fenêtre modale qui extrayait des données JSON dans un tableau, mais je l'ai essayé à l'aide de l'exemple, et cela a fonctionné:
var modal = document.getElementById('demodal');
$('#ampersandcontent').text(replaceAll(data[0],"&", "&"));
J'aime ça parce que c'était simple et que ça marche, mais je ne sais pas pourquoi ce n'est pas très utilisé. Cherché salut & bas pour trouver une solution simple. Je continue à chercher à comprendre la syntaxe, et s'il y a un risque à l'utiliser. Je n'ai encore rien trouvé.