Eu tenho algum código Javascript que se comunica com um back-end XML-RPC. O XML-RPC retorna cadeias de caracteres do formulário:
<img src='myimage.jpg'>
No entanto, quando eu uso o Javascript para inserir as strings no HTML, elas são renderizadas literalmente. Não vejo uma imagem, literalmente vejo a sequência:
<img src='myimage.jpg'>
Meu palpite é que o HTML está sendo escapado pelo canal XML-RPC.
Como posso retirar a string em Javascript? Tentei as técnicas desta página sem êxito: http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/
Quais são as outras maneiras de diagnosticar o problema?
javascript
html
escaping
xml-rpc
Joseph Turian
fonte
fonte
Respostas:
EDIT: você deve usar a API DOMParser como Wladimir sugere ; editei minha resposta anterior, pois a função postada introduziu uma vulnerabilidade de segurança.
O seguinte trecho é o código da resposta antiga com uma pequena modificação: o uso de um em
textarea
vez de umdiv
reduz a vulnerabilidade do XSS, mas ainda é problemático no IE9 e no Firefox.Basicamente, crio um elemento DOM programaticamente, atribuo o HTML codificado ao innerHTML e recupero o nodeValue do nó de texto criado na inserção innerHTML. Como ele apenas cria um elemento, mas nunca o adiciona, nenhum HTML do site é modificado.
Ele funcionará em vários navegadores (incluindo navegadores antigos) e aceitará todas as entidades de caracteres HTML .
EDIT: A versão antiga deste código não funcionava no IE com entradas em branco, como evidenciado aqui no jsFiddle (exibição no IE). A versão acima funciona com todas as entradas.
UPDATE: parece que isso não funciona com cadeias grandes e também apresenta uma vulnerabilidade de segurança , consulte os comentários.
fonte
'
não pertence às entidades HTML 4, é por isso! w3.org/TR/html4/sgml/entities.html fishbowl.pastiche.org/2003/07/01/the_curse_of_aposA maioria das respostas fornecidas aqui tem uma enorme desvantagem: se a string que você está tentando converter não for confiável, você terá uma vulnerabilidade de Cross-Site Scripting (XSS) . Para a função na resposta aceita , considere o seguinte:
A string aqui contém uma tag HTML sem escape, portanto, em vez de decodificar qualquer coisa, a
htmlDecode
função realmente executará o código JavaScript especificado dentro da string.Isso pode ser evitado usando o DOMParser, compatível com todos os navegadores modernos :
É garantido que esta função não execute nenhum código JavaScript como efeito colateral. Quaisquer tags HTML serão ignoradas, apenas o conteúdo do texto será retornado.
Nota de compatibilidade : a análise de HTML
DOMParser
requer pelo menos o Chrome 30, Firefox 12, Opera 17, Internet Explorer 10, Safari 7.1 ou Microsoft Edge. Portanto, todos os navegadores sem suporte já ultrapassaram a EOL e, a partir de 2017, os únicos que ainda podem ser vistos na natureza ocasionalmente são as versões mais antigas do Internet Explorer e Safari (geralmente essas ainda não são numerosas o suficiente para incomodar).fonte
DOMParser
não era compatível com o"text/html"
Firefox 12.0 e ainda existem algumas versões mais recentes de navegadores que nem mesmo são compatíveisDOMParser.prototype.parseFromString()
. De acordo com sua referência,DOMParser
ainda é uma tecnologia experimental, e os substitutos usam ainnerHTML
propriedade que, como você também apontou em resposta à minha abordagem , tem essa vulnerabilidade XSS (que deve ser corrigida pelos fornecedores de navegadores).<script>
tags que não estão sendo executadas não são um mecanismo de segurança; essa regra evita os problemas complicados de temporização se a configuraçãoinnerHTML
puder executar scripts síncronos como efeito colateral. A limpeza do código HTML é um assunto complicado einnerHTML
nem sequer tenta - já porque a página da Web pode realmente pretender definir manipuladores de eventos em linha. Isso simplesmente não é um mecanismo destinado a dados inseguros, ponto final.Se você estiver usando jQuery:
Caso contrário, use o Encoder Object da Strictly Software , que possui uma excelente
htmlDecode()
função.fonte
O truque é usar o poder do navegador para decodificar os caracteres HTML especiais, mas não permitir que o navegador execute os resultados como se fosse um html real ... Essa função usa um regex para identificar e substituir caracteres HTML codificados, um caractere de uma vez.
fonte
/\&#?[0-9a-z]+;/gi
já que # deve aparecer apenas como o segundo caractere, se for o caso.A resposta do CMS funciona bem, a menos que o HTML que você deseja remover seja muito longo, maior que 65536 caracteres. Como, no Chrome, o HTML interno é dividido em muitos nós filhos, cada um com 65536 no máximo, e você precisa concatená-los. Essa função também funciona para strings muito longas:
Consulte esta resposta sobre o
innerHTML
comprimento máximo para obter mais informações: https://stackoverflow.com/a/27545633/694469fonte
Não é uma resposta direta à sua pergunta, mas não seria melhor para o seu RPC retornar alguma estrutura (XML ou JSON ou qualquer outra coisa) com esses dados de imagem (URLs no seu exemplo) dentro dessa estrutura?
Então você pode simplesmente analisá-lo em seu javascript e criar o
<img>
próprio javascript em uso.A estrutura que você recebe do RPC pode ter a seguinte aparência:
Eu acho que é melhor assim, pois a injeção de um código que vem de fonte externa para a sua página não parece muito segura. Imaginando alguém sequestrando seu script XML-RPC e colocando algo que você não gostaria lá (até mesmo algum javascript ...)
fonte
htmlDecode("<img src='myimage.jpg'><script>alert('xxxxx');</script>")
e nada aconteceu. Eu recebi a string html decodificada de volta, conforme o esperado.A resposta de Chris é agradável e elegante, mas falha se o valor for indefinido . Apenas uma simples melhoria torna sólida:
fonte
return (typeof value !== 'string') ? '' : $('<div/>').html(value).text();
Você é bem-vindo ... apenas um mensageiro ... o crédito total vai para ourcodeworld.com, link abaixo.
Crédito completo: https://ourcodeworld.com/articles/read/188/encode-and-decode-html-entities-using-pure-javascript
fonte
Esta é a solução mais abrangente que eu tentei até agora:
fonte
Eu era louco o suficiente para fazer essa função que deveria ser bonita, se não completamente, exaustiva:
Usado assim:
Impressões:
Ich Heiße David
PS: demorou uma hora e meia para fazer.
fonte
Para desescapar entidades HTML * em JavaScript, você pode usar a pequena biblioteca html-escaper :
npm install html-escaper
Ou
unescape
função de Lodash ou sublinhado , se você estiver usando-o.*) Por favor, note que estas funções não cobrem todas as entidades HTML, mas apenas as mais comuns, ou seja
&
,<
,>
,'
,"
. Para unescape todas as entidades HTML, você pode usar ele biblioteca.fonte
Uso isso no meu projeto: inspirado em outras respostas, mas com um parâmetro extra seguro, pode ser útil quando você lida com caracteres decorados
E é utilizável como:
fonte
Todas as outras respostas aqui têm problemas.
Os métodos document.createElement ('div') (incluindo aqueles que usam jQuery) executam qualquer javascript passado (um problema de segurança) e o método DOMParser.parseFromString () apara os espaços em branco. Aqui está uma solução javascript pura que não tem nenhum problema:
TextArea é usado especificamente para evitar o código executig js. Passa estes:
fonte
htmlDecode("</textarea><img src=x onerror=alert(1)>")
. Você postou isso depois que eu já apontei esse problema na resposta de Sergio Belevskij.fonte
Existe uma variante 80% mais produtiva do que as respostas no topo.
Consulte o benchmark: https://jsperf.com/decode-html12345678/1
Se você precisar deixar tags, remova as duas
.replace(...)
chamadas (você pode deixar a primeira se não precisar de scripts).fonte
decodeEntities("</textarea '><img src=x onerror=alert(1) \">")
para o Firefox. Pare de tentar limpar o código HTML com expressões regulares.