Retire o HTML do JavaScript de texto

655

Existe uma maneira fácil de pegar uma string de html em JavaScript e remover o html?

Bryan
fonte

Respostas:

761

Se você estiver executando em um navegador, a maneira mais fácil é permitir que o navegador faça isso por você ...

function stripHtml(html)
{
   var tmp = document.createElement("DIV");
   tmp.innerHTML = html;
   return tmp.textContent || tmp.innerText || "";
}

Nota: como as pessoas observaram nos comentários, é melhor evitar isso se você não controlar a fonte do HTML (por exemplo, não execute isso em nada que possa ter vindo da entrada do usuário). Para esses cenários, você ainda pode deixar o navegador fazer o trabalho por você - consulte a resposta da Saba sobre o uso do agora amplamente disponível DOMParser .

Shog9
fonte
40
Lembre-se de que essa abordagem é bastante inconsistente e falhará ao remover determinados caracteres em determinados navegadores. Por exemplo, em Prototype.js, usamos esta abordagem para o desempenho, mas o trabalho em torno de algumas das deficiências - github.com/kangax/prototype/blob/...
kangax
11
Lembre-se de que seu espaço em branco será bagunçado. Eu costumava usar esse método e, em seguida, tinha problemas, pois certos códigos de produto continham espaços duplos, que acabavam em espaços únicos depois que eu recebia o internalText do DIV. Em seguida, os códigos do produto não corresponderam mais tarde no aplicativo.
Magnus Smith
11
@ Magnus Smith: Sim, se um espaço em branco é uma preocupação - ou realmente, se você precisar de algum texto que não envolva diretamente o DOM HTML específico com o qual você está trabalhando -, será melhor usar um do outro soluções dadas aqui. As principais vantagens desse método são: 1) trivial e 2) processam de forma confiável tags, espaços em branco, entidades, comentários etc. da mesma maneira que o navegador em que você está rodando . Isso é frequentemente útil para o código do cliente da Web, mas não necessariamente apropriado para interagir com outros sistemas em que as regras são diferentes.
Shog9
220
Não use isso com HTML de uma fonte não confiável. Para ver o porquê, tente executarstrip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Mike Samuel
24
Se o html contiver imagens (tags img), as imagens serão solicitadas pelo navegador. Isso não é bom.
21413
591
myString.replace(/<[^>]*>?/gm, '');
nickf
fonte
4
Não funciona <img src=http://www.google.com.kh/images/srpr/nav_logo27.png onload="alert(42)" se você estiver injetando via document.writeou concatenando com uma string que contém a >antes de injetar via innerHTML.
Mike Samuel
1
@PerishableDave, concordo que o >restante será deixado no segundo. Isso não representa um risco de injeção. O risco ocorre devido à <esquerda no primeiro, o que faz com que o analisador HTML esteja em um contexto diferente do estado dos dados quando o segundo é iniciado. Observe que não há transição do estado dos dados >.
Mike Samuel
73
@MikeSamuel Já decidimos sobre esta resposta? Usuário ingênuo aqui pronto para copiar e colar.
Ziggy
1
Isso também, acredito, fica completamente confuso se for dado algo como <button onClick="dostuff('>');"></button>Assumindo HTML corretamente escrito, você ainda precisa levar em conta que um sinal maior que pode estar em algum lugar no texto citado em um atributo. Além disso, você deseja remover todo o texto dentro das <script>tags, pelo menos.
21413 Jonathon
15
@AntonioMax, respondi a essa pergunta ad nauseam , mas ao conteúdo da sua pergunta, porque o código crítico de segurança não deve ser copiado e colado. Você deve fazer o download de uma biblioteca e mantê-la atualizada e corrigida para garantir a segurança contra vulnerabilidades descobertas recentemente e alterações nos navegadores.
Mike Samuel
249

Maneira mais simples:

jQuery(html).text();

Isso recupera todo o texto de uma string de html.

Marca
fonte
111
Sempre usamos o jQuery para projetos, pois, invariavelmente, nossos projetos têm muito Javascript. Portanto nós não adicionar volume, aproveitamos código API existente ...
Mark
32
Você o usa, mas o OP pode não. a pergunta era sobre Javascript e não JQuery.
Dementic
105
Ainda é uma resposta útil para pessoas que precisam fazer a mesma coisa que o OP (como eu) e não se importam em usar jQuery (como eu), sem mencionar que poderia ter sido útil para o OP se estivessem pensando em usar jQuery. O objetivo do site é compartilhar conhecimento. Lembre-se de que o efeito assustador que você pode ter castigando respostas úteis sem uma boa razão.
Acjay
27
@ Dementic chocante, acho os tópicos com várias respostas os mais úteis, porque muitas vezes uma resposta secundária atende às minhas necessidades exatas, enquanto a resposta primária atende ao caso geral.
Eric Goldberg
36
Isso não funcionará se alguma parte da string não estiver envolvida na tag html. por exemplo, "<b> Erro: </b> digite um e-mail válido" retornará apenas "Erro:"
Aamir Afridi
127

Eu gostaria de compartilhar uma versão editada da resposta aprovada do Shog9 .


Como Mike Samuel apontou com um comentário, essa função pode executar códigos javascript embutidos.
Mas Shog9 está certo ao dizer "deixe o navegador fazer isso por você ..."

então .. aqui minha versão editada, usando DOMParser :

function strip(html){
   var doc = new DOMParser().parseFromString(html, 'text/html');
   return doc.body.textContent || "";
}

aqui o código para testar o javascript embutido:

strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")

Além disso, ele não solicita recursos na análise (como imagens)

strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
Sabaz
fonte
3
Vale acrescentar que esta solução funciona apenas no navegador.
22418 Kris_IV
1
Isso não é uma tag strip, mas mais como o PHP htmlspecialchars (). Ainda é útil para mim.
Daantje
Observe que isso também remove os espaços em branco do início do texto.
Raine Revere
Também a nota, este funciona em Web Workers
Chris Seufert
Isso parece ser muito mais rápido do que a resposta de @ Shog9
Shmuel Kamensky
55

Como uma extensão do método jQuery, se a sua string não puder conter HTML (por exemplo, se você estiver tentando remover HTML de um campo de formulário)

jQuery(html).text();`

retornará uma string vazia se não houver HTML

Usar:

jQuery('<p>' + html + '</p>').text();

em vez de.

Atualização: Como foi indicado nos comentários, em algumas circunstâncias esta solução executará javascript contido htmlse o valor de htmlpuder ser influenciado por um invasor, use uma solução diferente.

user999305
fonte
12
Ou$("<p>").html(html).text();
Dimitar Dimitrov
4
Isso ainda executa o código provavelmente perigosojQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
Simon
tente jQuery ("aa & # X003c; script> alert (1) & # X003c; / script> a"). text ();
Grzegorz Kaczan
41

Convertendo HTML para email de texto sem formatação, mantendo os hiperlinks (a href) intactos

A função acima postada pelo hipóxido funciona bem, mas eu estava atrás de algo que basicamente convertia o HTML criado em um editor Web RichText (por exemplo, FCKEditor) e limpava todo o HTML, mas deixava todos os links devido ao fato de que eu queria tanto o HTML quanto o HTML. a versão em texto sem formatação para ajudar a criar as partes corretas para um email do STMP (HTML e texto sem formatação).

Depois de muito tempo pesquisando no Google, eu e meus colegas descobrimos isso usando o mecanismo de expressão regular em Javascript:

str='this string has <i>html</i> code i want to <b>remove</b><br>Link Number 1 -><a href="http://www.bbc.co.uk">BBC</a> Link Number 1<br><p>Now back to normal text and stuff</p>
';
str=str.replace(/<br>/gi, "\n");
str=str.replace(/<p.*>/gi, "\n");
str=str.replace(/<a.*href="(.*?)".*>(.*?)<\/a>/gi, " $2 (Link->$1) ");
str=str.replace(/<(?:.|\s)*?>/g, "");

a strvariável começa assim:

this string has <i>html</i> code i want to <b>remove</b><br>Link Number 1 -><a href="http://www.bbc.co.uk">BBC</a> Link Number 1<br><p>Now back to normal text and stuff</p>

e depois que o código foi executado, fica assim: -

this string has html code i want to remove
Link Number 1 -> BBC (Link->http://www.bbc.co.uk)  Link Number 1


Now back to normal text and stuff

Como você pode ver, todo o HTML foi removido e o Link foi mantido com o texto com hiperlink ainda intacto. Também substituí as tags <p>e <br>por \n(newline char) para que algum tipo de formatação visual seja mantida.

Para alterar o formato do link (por exemplo BBC (Link->http://www.bbc.co.uk)), basta editar o $2 (Link->$1), onde $1está o URL / URI href e o $2texto com hiperlink. Com os links diretamente no corpo do texto sem formatação, a maioria dos clientes de email SMTP os converte para que o usuário possa clicar neles.

Espero que você ache isso útil.

Jibberboy2000
fonte
Ele não suporta "& nbsp;"
Rose Nettoyeur
33

Uma melhoria na resposta aceita.

function strip(html)
{
   var tmp = document.implementation.createHTMLDocument("New").body;
   tmp.innerHTML = html;
   return tmp.textContent || tmp.innerText || "";
}

Dessa forma, algo funcionando assim não fará mal:

strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")

Firefox, Chromium e Explorer 9+ são seguros. O Opera Presto ainda é vulnerável. As imagens mencionadas nas seqüências também não são baixadas no Chromium e Firefox, salvando solicitações http.

Janghou
fonte
Isto é parte do caminho até lá, mas não está a salvo.<script><script>alert();
Arth
1
Isso não executa nenhum script aqui no Chromium / Opera / Firefox no Linux, então por que não é seguro?
Janghou
Minhas desculpas, devo ter testado erroneamente, provavelmente esqueci de clicar em executar novamente no jsFiddle.
Arth
O argumento "Novo" é supérfluo, eu acho?
Jon Schneider
De acordo com as especificações , é opcional hoje em dia, mas nem sempre foi.
Janghou
23

Isso deve funcionar em qualquer ambiente Javascript (NodeJS incluído).

const text = `
<html lang="en">
  <head>
    <style type="text/css">*{color:red}</style>
    <script>alert('hello')</script>
  </head>
  <body><b>This is some text</b><br/><body>
</html>`;

// Remove style tags and content
text.replace(/<style[^>]*>.*<\/style>/gm, '')
    // Remove script tags and content
    .replace(/<script[^>]*>.*<\/script>/gm, '')
    // Remove all opening, closing and orphan HTML tags
    .replace(/<[^>]+>/gm, '')
    // Remove leading spaces and repeated CR/LF
    .replace(/([\r\n]+ +)+/gm, '');
Karl.S
fonte
@pstanton você poderia dar um exemplo prático de sua declaração?
Karl.S
3
<html><style..>* {font-family:comic-sans;}</style>Some Text</html>
pstanton
@pstanton Corrigi o código e adicionei comentários, desculpe pela resposta tardia.
precisa saber é o seguinte
16

Eu alterei a resposta de Jibberboy2000 para incluir vários <BR />formatos de tag, remova tudo dentro <SCRIPT>e <STYLE>etiquetas, formatar o HTML resultante, removendo várias quebras de linha e espaços e converter alguns códigos HTML-codificado em normal. Após alguns testes, parece que você pode converter a maioria das páginas da Web completas em texto simples, onde o título e o conteúdo da página são mantidos.

No exemplo simples,

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!--comment-->

<head>

<title>This is my title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style>

    body {margin-top: 15px;}
    a { color: #D80C1F; font-weight:bold; text-decoration:none; }

</style>
</head>

<body>
    <center>
        This string has <i>html</i> code i want to <b>remove</b><br>
        In this line <a href="http://www.bbc.co.uk">BBC</a> with link is mentioned.<br/>Now back to &quot;normal text&quot; and stuff using &lt;html encoding&gt;                 
    </center>
</body>
</html>

torna-se

Este é o meu título

Esta cadeia tem código html que eu quero remover

Nesta linha é mencionada a BBC ( http://www.bbc.co.uk ) com link.

Agora, de volta ao "texto normal" e outras coisas usando

A função JavaScript e a página de teste têm esta aparência:

function convertHtmlToText() {
    var inputText = document.getElementById("input").value;
    var returnText = "" + inputText;

    //-- remove BR tags and replace them with line break
    returnText=returnText.replace(/<br>/gi, "\n");
    returnText=returnText.replace(/<br\s\/>/gi, "\n");
    returnText=returnText.replace(/<br\/>/gi, "\n");

    //-- remove P and A tags but preserve what's inside of them
    returnText=returnText.replace(/<p.*>/gi, "\n");
    returnText=returnText.replace(/<a.*href="(.*?)".*>(.*?)<\/a>/gi, " $2 ($1)");

    //-- remove all inside SCRIPT and STYLE tags
    returnText=returnText.replace(/<script.*>[\w\W]{1,}(.*?)[\w\W]{1,}<\/script>/gi, "");
    returnText=returnText.replace(/<style.*>[\w\W]{1,}(.*?)[\w\W]{1,}<\/style>/gi, "");
    //-- remove all else
    returnText=returnText.replace(/<(?:.|\s)*?>/g, "");

    //-- get rid of more than 2 multiple line breaks:
    returnText=returnText.replace(/(?:(?:\r\n|\r|\n)\s*){2,}/gim, "\n\n");

    //-- get rid of more than 2 spaces:
    returnText = returnText.replace(/ +(?= )/g,'');

    //-- get rid of html-encoded characters:
    returnText=returnText.replace(/&nbsp;/gi," ");
    returnText=returnText.replace(/&amp;/gi,"&");
    returnText=returnText.replace(/&quot;/gi,'"');
    returnText=returnText.replace(/&lt;/gi,'<');
    returnText=returnText.replace(/&gt;/gi,'>');

    //-- return
    document.getElementById("output").value = returnText;
}

Foi usado com este HTML:

<textarea id="input" style="width: 400px; height: 300px;"></textarea><br />
<button onclick="convertHtmlToText()">CONVERT</button><br />
<textarea id="output" style="width: 400px; height: 300px;"></textarea><br />
Elendurwen
fonte
1
Eu gosto dessa solução porque ela tem tratamento de caracteres especiais html ... mas ainda não são suficientes ... a melhor resposta para mim seria lidar com todos eles. (que é provavelmente o que o jquery faz).
Daniel Gerson
2
Eu acho que /<p.*>/gideveria ser /<p.*?>/gi.
cbron 5/05
Note que para remover todas as <br>tags que você poderia usar uma boa expressão regular em vez disso: /<br\s*\/?>/de que maneira você tem apenas uma substituição em vez de 3. Além disso, parece-me que, exceto para a decodificação de entidades que você pode ter um único regex, algo como isto: /<[a-z].*?\/?>/.
Alexis Wilke
Bom roteiro. Mas e o conteúdo da tabela? Alguma idéia de como ele pode ser exibido
Hristo Enev
@DanielGerson, codificação html fica peludo real, real rápido, mas a melhor abordagem parece estar usando o que ele biblioteca
KyleMit
15
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");

Esta é uma versão regex, que é mais resistente a HTML malformado, como:

Tags não fechadas

Some text <img

"<", ">" dentro dos atributos da tag

Some text <img alt="x > y">

Novas linhas

Some <a href="http://google.com">

O código

var html = '<br>This <img alt="a>b" \r\n src="a_b.gif" />is > \nmy<>< > <a>"text"</a'
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
hegemon
fonte
7

Outra solução, reconhecidamente menos elegante que a do nickf ou do Shog9, seria percorrer recursivamente o DOM começando na tag <body> e anexando cada nó de texto.

var bodyContent = document.getElementsByTagName('body')[0];
var result = appendTextNodes(bodyContent);

function appendTextNodes(element) {
    var text = '';

    // Loop through the childNodes of the passed in element
    for (var i = 0, len = element.childNodes.length; i < len; i++) {
        // Get a reference to the current child
        var node = element.childNodes[i];
        // Append the node's value if it's a text node
        if (node.nodeType == 3) {
            text += node.nodeValue;
        }
        // Recurse through the node's children, if there are any
        if (node.childNodes.length > 0) {
            appendTextNodes(node);
        }
    }
    // Return the final result
    return text;
}
Bryan
fonte
3
caramba. se você estiver criando uma árvore DOM a partir da sua string, use o caminho do shog!
nickf
Sim, minha solução empunha um martelo onde um martelo comum é mais apropriado :-). E eu concordo que as suas e as soluções da Shog9 são melhores, e basicamente disseram o mesmo na resposta. Também não consegui refletir em minha resposta que o html já está contido em uma string, tornando minha resposta essencialmente inútil em relação à pergunta original. :-(
Bryan
1
Para ser justo, isso tem valor - se você absolutamente deve preservar / todo / todo o texto, isso tem pelo menos uma chance decente de capturar novas linhas, guias, retornos de carro, etc. e faça muito mais rápido ... eh.
219 Shog9
7

Se você deseja manter os links e a estrutura do conteúdo (h1, h2, etc), verifique TextVersionJS Você pode usá-lo com qualquer HTML, embora tenha sido criado para converter um email em HTML em texto sem formatação.

O uso é muito simples. Por exemplo em node.js:

var createTextVersion = require("textversionjs");
var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";

var textVersion = createTextVersion(yourHtml);

Ou no navegador com js puro:

<script src="textversion.js"></script>
<script>
  var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
  var textVersion = createTextVersion(yourHtml);
</script>

Também funciona com o require.js:

define(["textversionjs"], function(createTextVersion) {
  var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
  var textVersion = createTextVersion(yourHtml);
});
gyula.nemeth
fonte
4

Depois de tentar todas as respostas mais mencionadas, se não todas, elas tiveram casos extremos e não conseguiram atender completamente minhas necessidades.

Comecei a explorar como o php faz isso e me deparei com a lib php.js, que replica o método strip_tags aqui: http://phpjs.org/functions/strip_tags/

Deminetix
fonte
Esta é uma função elegante e bem documentada. No entanto, ele pode ser feito mais rápido quando allowed == ''que eu acho que é o que o OP pediu, que é quase o que Byron respondeu abaixo (Byron só tem o [^>]errado.)
Alexis Wilke
1
Se você usar o allowedparam você está vulnerável a XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')retornos<p onclick="alert(1)">mytext</p>
Chris Cinelli
4
function stripHTML(my_string){
    var charArr   = my_string.split(''),
        resultArr = [],
        htmlZone  = 0,
        quoteZone = 0;
    for( x=0; x < charArr.length; x++ ){
     switch( charArr[x] + htmlZone + quoteZone ){
       case "<00" : htmlZone  = 1;break;
       case ">10" : htmlZone  = 0;resultArr.push(' ');break;
       case '"10' : quoteZone = 1;break;
       case "'10" : quoteZone = 2;break;
       case '"11' : 
       case "'12" : quoteZone = 0;break;
       default    : if(!htmlZone){ resultArr.push(charArr[x]); }
     }
    }
    return resultArr.join('');
}

É responsável por> atributos internos e <img onerror="javascript">por elementos dom recém-criados.

uso:

clean_string = stripHTML("string with <html> in it")

demo:

https://jsfiddle.net/gaby_de_wilde/pqayphzd/

demonstração da resposta principal fazendo as coisas terríveis:

https://jsfiddle.net/gaby_de_wilde/6f0jymL6/1/

user40521
fonte
Você também precisará lidar com aspas escapadas dentro de um valor de atributo (por exemplo string with <a malicious="attribute \">this text should be removed, but is not">example</a>).
Logan Pickup
4

Muitas pessoas já responderam isso, mas achei que seria útil compartilhar a função que escrevi que retira as tags HTML de uma string, mas permite incluir uma matriz de tags que você não deseja remover. É bem curto e tem funcionado muito bem para mim.

function removeTags(string, array){
  return array ? string.split("<").filter(function(val){ return f(array, val); }).map(function(val){ return f(array, val); }).join("") : string.split("<").map(function(d){ return d.split(">").pop(); }).join("");
  function f(array, value){
    return array.map(function(d){ return value.includes(d + ">"); }).indexOf(true) != -1 ? "<" + value : value.split(">")[1];
  }
}

var x = "<span><i>Hello</i> <b>world</b>!</span>";
console.log(removeTags(x)); // Hello world!
console.log(removeTags(x, ["span", "i"])); // <span><i>Hello</i> world!</span>
Harry Stevens
fonte
3

Eu acho que a maneira mais fácil é usar expressões regulares como alguém mencionado acima. Embora não haja motivo para usar um monte deles. Tentar:

stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
Byron Carasco
fonte
11
Não faça isso se você se preocupa com segurança. Se a entrada do usuário for esta: '<scr <script> ipt> alert (42); </ scr </script> ipt>', a versão removida será a seguinte: '<script> alert (42); </ script > '. Portanto, esta é uma vulnerabilidade XSS.
molnarg
Você deve alterar o [^<>]com [^>]porque uma tag válida não pode incluir um <caractere e a vulnerabilidade XSS desaparece.
Alexis Wilke
3

Fiz algumas modificações no script Jibberboy2000 original Espero que seja útil para alguém

str = '**ANY HTML CONTENT HERE**';

str=str.replace(/<\s*br\/*>/gi, "\n");
str=str.replace(/<\s*a.*href="(.*?)".*>(.*?)<\/a>/gi, " $2 (Link->$1) ");
str=str.replace(/<\s*\/*.+?>/ig, "\n");
str=str.replace(/ {2,}/gi, " ");
str=str.replace(/\n+\s*/gi, "\n\n");
Jaxolotl
fonte
3

Aqui está uma versão que aborda as preocupações de segurança de @ MikeSamuel:

function strip(html)
{
   try {
       var doc = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null);
       doc.documentElement.innerHTML = html;
       return doc.documentElement.textContent||doc.documentElement.innerText;
   } catch(e) {
       return "";
   }
}

Observe que ele retornará uma string vazia se a marcação HTML não for XML válido (ou seja, as tags devem ser fechadas e os atributos devem ser citados). Isso não é o ideal, mas evita a questão de ter o potencial de explorar a segurança.

Se não é necessário ter uma marcação XML válida, você pode tentar usar:

var doc = document.implementation.createHTMLDocument("");

mas essa não é uma solução perfeita por outras razões.

Jeremy Johnstone
fonte
Que irá falhar em muitas circunstâncias, se o texto vem de entrada do usuário (textarea ou widget contenteditable ...)
Alexis Wilke
3

Você pode remover com segurança as tags html usando o atributo sandbox iframe .

A idéia aqui é que, em vez de tentar regexar nossa string, aproveitamos o analisador nativo do navegador injetando o texto em um elemento DOM e consultando a propriedade textContent/ innerTextdesse elemento.

O elemento mais adequado para injetar nosso texto é um iframe em área restrita, para impedir qualquer execução arbitrária de código (também conhecido como XSS ).

A desvantagem dessa abordagem é que ela só funciona em navegadores.

Aqui está o que eu criei (Não testado em batalha):

const stripHtmlTags = (() => {
  const sandbox = document.createElement("iframe");
  sandbox.sandbox = "allow-same-origin"; // <--- This is the key
  sandbox.style.setProperty("display", "none", "important");

  // Inject the sanbox in the current document
  document.body.appendChild(sandbox);

  // Get the sandbox's context
  const sanboxContext = sandbox.contentWindow.document;

  return (untrustedString) => {
    if (typeof untrustedString !== "string") return ""; 

    // Write the untrusted string in the iframe's body
    sanboxContext.open();
    sanboxContext.write(untrustedString);
    sanboxContext.close();

    // Get the string without html
    return sanboxContext.body.textContent || sanboxContext.body.innerText || "";
  };
})();

Uso ( demo ):

console.log(stripHtmlTags(`<img onerror='alert("could run arbitrary JS here")' src='bogus'>XSS injection :)`));
console.log(stripHtmlTags(`<script>alert("awdawd");</` + `script>Script tag injection :)`));
console.log(stripHtmlTags(`<strong>I am bold text</strong>`));
console.log(stripHtmlTags(`<html>I'm a HTML tag</html>`));
console.log(stripHtmlTags(`<body>I'm a body tag</body>`));
console.log(stripHtmlTags(`<head>I'm a head tag</head>`));
console.log(stripHtmlTags(null));
Etienne Martin
fonte
Ótima solução para ambientes baseados na Web! Provavelmente, você não deve usar um IIFE, já que desde o ECMAScript 2015, as variáveis ​​com escopo de bloco já estão com escopo definido no bloco corretamente com os operadores lete const. Além disso, usando sua solução, tenho muitas referências de iframesnão usadas dentro do documento. Considere adicionar um document.body.removeChild(sandbox)no código para futuros leitores baseados em pasta de cópia.
Amin NAIRI 5/08/19
2

Com o jQuery, você pode simplesmente recuperá-lo usando

$('#elementID').text()
ianaz
fonte
2

O código abaixo permite que você retenha algumas tags html enquanto remove todas as outras

function strip_tags(input, allowed) {

  allowed = (((allowed || '') + '')
    .toLowerCase()
    .match(/<[a-z][a-z0-9]*>/g) || [])
    .join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)

  var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
      commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;

  return input.replace(commentsAndPhpTags, '')
      .replace(tags, function($0, $1) {
          return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
      });
}
aWebDeveloper
fonte
1
Você deve citar a fonte ( phpjs). Se você usar o allowedparam você está vulnerável a XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')retornos<p onclick="alert(1)">mytext</p>
Chris Cinelli
2

Também é possível usar o fantástico analisador HTML HTML puro htmlparser2 . Aqui está uma demonstração de trabalho:

var htmlparser = require('htmlparser2');

var body = '<p><div>This is </div>a <span>simple </span> <img src="test"></img>example.</p>';

var result = [];

var parser = new htmlparser.Parser({
    ontext: function(text){
        result.push(text);
    }
}, {decodeEntities: true});

parser.write(body);
parser.end();

result.join('');

A saída será This is a simple example.

Veja em ação aqui: https://tonicdev.com/jfahrenkrug/extract-text-from-html

Isso funciona no nó e no navegador se você compactar seu aplicativo da Web usando uma ferramenta como o webpack.

Johannes Fahrenkrug
fonte
2

Eu só precisava tirar o <a> tags e substituí-las pelo texto do link.

Isso parece funcionar muito bem.

htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');
FrigginGlorious
fonte
Isso se aplica apenas a tags e precisa ser ajustado para ser uma função ampla.
M3nda
Sim, além de uma marca de âncora poderia ter muitos outros atributos, como o title="...".
Alexis Wilke
1

Eu mesmo criei uma expressão regular de trabalho:

str=str.replace(/(<\?[a-z]*(\s[^>]*)?\?(>|$)|<!\[[a-z]*\[|\]\]>|<!DOCTYPE[^>]*?(>|$)|<!--[\s\S]*?(-->|$)|<[a-z?!\/]([a-z0-9_:.])*(\s[^>]*)?(>|$))/gi, ''); 
MarekJ47
fonte
1

jquery simples de 2 linhas para remover o html.

 var content = "<p>checking the html source&nbsp;</p><p>&nbsp;
  </p><p>with&nbsp;</p><p>all</p><p>the html&nbsp;</p><p>content</p>";

 var text = $(content).text();//It gets you the plain text
 console.log(text);//check the data in your console

 cj("#text_area_id").val(text);//set your content to text area using text_area_id
Desenvolvedor
fonte
1

A resposta aceita funciona bem principalmente, no entanto, no IE, se a htmlstring é a que nullvocê obtém "null"(em vez de ''). Fixo:

function strip(html)
{
   if (html == null) return "";
   var tmp = document.createElement("DIV");
   tmp.innerHTML = html;
   return tmp.textContent || tmp.innerText || "";
}
basarat
fonte
1

Usando o Jquery:

function stripTags() {
    return $('<p></p>').html(textToEscape).text()
}
math2001
fonte
1

inputO elemento suporta apenas um texto de linha :

O estado do texto representa um controle de edição de texto simples de uma linha para o valor do elemento.

function stripHtml(str) {
  var tmp = document.createElement('input');
  tmp.value = str;
  return tmp.value;
}

Atualização: isso funciona conforme o esperado

function stripHtml(str) {
  // Remove some tags
  str = str.replace(/<[^>]+>/gim, '');

  // Remove BB code
  str = str.replace(/\[(\w+)[^\]]*](.*?)\[\/\1]/g, '$2 ');

  // Remove html and line breaks
  const div = document.createElement('div');
  div.innerHTML = str;

  const input = document.createElement('input');
  input.value = div.textContent || div.innerText || '';

  return input.value;
}
Mike Datsko
fonte
Não funciona, sempre mencione o navegador que você está usando ao postar uma resposta. Isso é impreciso e não funcionará no Chrome 61. As tags são renderizadas apenas como uma sequência.
precisa saber é o seguinte
0
    (function($){
        $.html2text = function(html) {
            if($('#scratch_pad').length === 0) {
                $('<div id="lh_scratch"></div>').appendTo('body');  
            }
            return $('#scratch_pad').html(html).text();
        };

    })(jQuery);

Defina isso como um plug-in jquery e use-o da seguinte maneira:

$.html2text(htmlContent);
Shiv Shankar
fonte
Vamos dizer que isso vem da entrada do usuário. Ele pode ser usado para adicionar scripts ou macros à sua página
Oluwatumbi