Respostas:
Nota de segurança: o uso desta resposta (preservada em sua forma original abaixo) pode introduzir uma vulnerabilidade XSS no seu aplicativo. Você não deve usar esta resposta. Leia a resposta de lucascaro para obter uma explicação das vulnerabilidades nesta resposta e use a abordagem dessa resposta ou a resposta de Mark Amery .
Na verdade, tente
var decoded = $("<div/>").html(encodedStr).text();
$("<div/>").html('<img src="http://www.google.com/images/logos/ps_logo2.png" onload=alert(1337)>')
. No Firefox ou Safari, ele dispara o alerta.
str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/g, "")
ou algo semelhante.
Sem jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
Isso funciona de maneira semelhante à resposta aceita , mas é seguro para uso com entradas não confiáveis do usuário.
Como observado por Mike Samuel , fazendo isso com um <div>
em vez de um <textarea>
com a entrada do usuário não confiável é uma vulnerabilidade de XSS, mesmo se a <div>
nunca é adicionado ao 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)">')
No entanto, esse ataque não é possível contra a <textarea>
porque não há elementos HTML com conteúdo permitido de a <textarea>
. Consequentemente, qualquer tag HTML ainda presente na string 'codificada' será automaticamente codificada por entidade pelo navegador.
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)">'))
Aviso : Fazer isso usando jQuery
.html()
e.val()
métodos em vez de usar.innerHTML
e.value
também é inseguro * para algumas versões do jQuery, mesmo ao usar atextarea
. Isso ocorre porque as versões mais antigas do jQuery avaliam deliberada e explicitamente os scripts contidos na cadeia de caracteres transmitida.html()
. Portanto, um código como este mostra um alerta no 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>
* Obrigado a Eru Penkman por capturar esta vulnerabilidade.
decodedString = textArea.value;
textArea.remove();
return decodedString;
if ('remove' in Element.prototype) textArea.remove();
$("<div />").html(string).text()
executará qualquer javascript na string fornecida , que eu suspeito é o que estava causando o seu problema. A resposta aceita deve ser atualizada para esta.
Como Mike Samuel disse, não use jQuery.html (). Text () para decodificar entidades html, pois é inseguro.
Em vez disso, use um processador de modelo como Mustache.js ou decodeEntities de @ comentário de VyvIT.
A biblioteca de utilitários do Underscore.js é fornecida com métodos escape
e unescape
, mas eles não são seguros para a entrada do usuário:
unescape
os documentos até agora, btw.
_.unescape("'")
resulta em apenas "& # 39;" em vez de aspas simples. Existe algo que eu estou ausente ou não sublinhado não escapa aos códigos de entidade HTML como mostrado em: w3schools.com/tags/ref_entities.asp
escape
eunescape
sublinhados ... não são seguros para a entrada do usuário" . O que você quer dizer com isso? Parece bobagem para mim, mas talvez eu esteja perdendo alguma coisa - você pode esclarecer?
_.unescape("<img src=fake onerror=alert('boo!')>")
(no Chrome / FF / IE). Mas não apareceu nenhum alerta. Tentei no console e coloquei no meu arquivo JS também. Mesmo resultado.
Eu acho que você está confundindo os métodos de texto e HTML. Veja este exemplo: se você usar o HTML interno de um elemento como texto, receberá tags HTML decodificadas (segundo botão). Mas se você usá-los como HTML, obterá a visualização formatada em HTML (primeiro botão).
<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>
Primeiro botão escreve: aqui está um conteúdo HTML .
O segundo botão grava: aqui está um conteúdo em <B> HTML </B>.
A propósito, você pode ver um plug-in que encontrei no plugin jQuery - o HTML decodifica e codifica que codifica e decodifica as strings HTML.
A questão é limitada por 'with jQuery', mas pode ser útil saber que o código jQuery fornecido na melhor resposta aqui faz o seguinte abaixo ... isso funciona com ou sem o jQuery:
function decodeEntities(input) {
var y = document.createElement('textarea');
y.innerHTML = input;
return y.value;
}
Você pode usar a biblioteca he , disponível em https://github.com/mathiasbynens/he
Exemplo:
console.log(he.decode("Jörg & Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
Eu desafiei o autor da biblioteca sobre a questão de saber se havia alguma razão para usar essa biblioteca no código do lado do cliente em favor do <textarea>
hack fornecido em outras respostas aqui e em outros lugares. Ele forneceu algumas justificativas possíveis:
Se você estiver usando o node.js.servidor, o uso de uma biblioteca para codificação / decodificação HTML fornece uma solução única que funciona tanto do lado do cliente quanto do lado do servidor.
Alguns algoritmos de decodificação de entidade dos navegadores possuem bugs ou faltam suporte para algumas referências de caracteres nomeadas . Por exemplo, o Internet Explorer decodificará e renderizará espaços não-quebráveis (
) corretamente, mas os reportará como espaços comuns, em vez de espaços não-quebráveis, através da innerText
propriedade de um elemento DOM , interrompendo o <textarea>
hack (embora apenas em menor grau). Além disso, o IE 8 e 9 simplesmente não suportam qualquer uma das novas referências personagem chamado adicionados em HTML 5. O autor que também abriga um teste de apoio de referência personagem chamado pelo http://mathias.html5.org/tests/html / referências de caracteres nomeados / . No IE 8, ele relata mais de mil erros.
Se você deseja se isolar dos bugs do navegador relacionados à decodificação de entidade e / ou conseguir lidar com toda a gama de referências de caracteres nomeados, não pode se safar do <textarea>
hack; você precisará de uma biblioteca como ele .
Ele simplesmente parece que fazer as coisas dessa maneira é menos invasivo.
codificar:
$("<textarea/>").html('<a>').html(); // return '<a>'
decodificar:
$("<textarea/>").html('<a>').val() // return '<a>'
Usar
myString = myString.replace( /\&/g, '&' );
É mais fácil fazê-lo no lado do servidor porque, aparentemente, o JavaScript não possui uma biblioteca nativa para lidar com entidades, nem encontrei nenhum próximo do topo dos resultados de pesquisa para as várias estruturas que estendem o JavaScript.
Procure por "entidades HTML JavaScript" e poderá encontrar algumas bibliotecas para esse fim, mas provavelmente todas elas serão construídas com base na lógica acima - substitua entidade por entidade.
Eu só precisava ter um caractere de entidade HTML (⇓) como valor para um botão HTML. O código HTML parece bom desde o início no navegador:
<input type="button" value="Embed & Share ⇓" id="share_button" />
Agora eu estava adicionando uma alternância que também deveria exibir o caractere. Esta é a minha solução
$("#share_button").toggle(
function(){
$("#share").slideDown();
$(this).attr("value", "Embed & Share " + $("<div>").html("⇑").text());
}
Isso exibe ⇓ novamente no botão. Espero que isso ajude alguém.
"Embed & Share \u21d1"
), ou melhor ainda, "Embed & Share ⇑"
se você puder servir seu script em UTF-8 (ou UTF-16, ou qualquer outra codificação que suporte o caractere)). Usar um elemento DOM para analisar uma entidade HTML apenas para transformar um caractere unicode arbitrário em uma string JavaScript é uma abordagem astuta e criativa que deixaria Rube Goldberg orgulhoso, mas não é uma boa prática; escapes unicode estão no idioma especificamente para lidar com este caso de uso.
Você precisa criar uma função personalizada para entidades html:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}
Suponha que você tenha abaixo de String.
Nossas cabines Deluxe são aconchegantes, aconchegantes e amplificadas; confortável
var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text(); // Now,decode html entities in your variable i.e
str e atribuir de volta a
tag.
é isso aí.
Para usuários do ExtJS, se você já possui a cadeia codificada, por exemplo, quando o valor retornado de uma função de biblioteca é o conteúdo innerHTML, considere esta função ExtJS:
Ext.util.Format.htmlDecode(innerHtmlContent)
Estenda uma classe String:
String::decode = ->
$('<textarea />').html(this).text()
e use como método:
"<img src='myimage.jpg'>".decode()
Tente o seguinte:
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 é uma função na biblioteca Jquery e retornará uma matriz que inclui alguns detalhes sobre a String fornecida.
em alguns casos, a String está sendo grande; portanto, a função separará o conteúdo em muitos índices.
e para obter todos os dados dos índices, você deve ir a qualquer índice e acessar o índice chamado "wholeText".
Eu escolhi o índice 0 porque ele funcionará em todos os casos (String pequena ou string grande).
Ainda há um problema: a seqüência de caracteres escapada não parece legível quando atribuída ao valor de entrada
var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);
Exapmle: https://jsfiddle.net/kjpdwmqa/3/
escape
método Underscore.js. Também não há explicação de como seu exemplo de código deve resolver o problema do OP.
Como alternativa, há também uma biblioteca para isso.
aqui, https://cdnjs.com/libraries/he
npm install he //using node.js
<script src="js/he.js"></script> //or from your javascript directory
O uso é o seguinte ...
//to encode text
he.encode('© Ande & Nonso® Company LImited 2018');
//to decode the
he.decode('© Ande & Nonso® Company Limited 2018');
Felicidades.
Para decodificar entidades HTML com jQuery, basta usar esta função:
function html_entity_decode(txt){
var randomID = Math.floor((Math.random()*100000)+1);
$('body').append('<div id="random'+randomID+'"></div>');
$('#random'+randomID).html(txt);
var entity_decoded = $('#random'+randomID).html();
$('#random'+randomID).remove();
return entity_decoded;
}
Como usar:
Javascript:
var txtEncoded = "á é í ó ú";
$('#some-id').val(html_entity_decode(txtEncoded));
HTML:
<input id="some-id" type="text" />
A maneira mais fácil é definir um seletor de classe para seus elementos e usar o seguinte código:
$(function(){
$('.classSelector').each(function(a, b){
$(b).html($(b).text());
});
});
Nada mais necessário!
Eu tive esse problema e encontrei esta solução clara e funciona bem.