Eliminar HTML del texto JavaScript

Respuestas:

763

Si está ejecutando en un navegador, entonces la forma más fácil es dejar que el navegador lo haga por usted ...

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

Nota: como la gente ha señalado en los comentarios, es mejor evitar esto si no controlas la fuente del HTML (por ejemplo, no ejecutes esto en nada que pueda provenir de la entrada del usuario). Para esos escenarios, aún puede dejar que el navegador haga el trabajo por usted: vea la respuesta de Saba sobre el uso del ahora disponible DOMParser .

Shog9
fuente
40
Solo recuerde que este enfoque es bastante inconsistente y no eliminará ciertos caracteres en ciertos navegadores. Por ejemplo, en Prototype.js, utilizamos este enfoque para el rendimiento, pero solucionamos
kangax
11
Recuerde que su espacio en blanco se verá afectado. Solía ​​usar este método, y luego tuve problemas, ya que ciertos códigos de productos contenían espacios dobles, que terminaron en espacios individuales después de recuperar el texto interno del DIV. Luego, los códigos de producto no coincidieron más adelante en la aplicación.
Magnus Smith
11
@Magnus Smith: Sí, si el espacio en blanco es una preocupación, o realmente, si tiene alguna necesidad de este texto que no involucre directamente el DOM HTML específico con el que está trabajando, entonces será mejor que use uno de los otros soluciones dadas aquí. Las principales ventajas de este método son que es 1) trivial y 2) procesará de manera confiable etiquetas, espacios en blanco, entidades, comentarios, etc. de la misma manera que el navegador en el que se está ejecutando . Con frecuencia, esto es útil para el código de cliente web, pero no necesariamente es apropiado para interactuar con otros sistemas donde las reglas son diferentes.
Shog9
220
No use esto con HTML de una fuente no confiable. Para ver por qué, intenta correrstrip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Mike Samuel
24
Si html contiene imágenes (etiquetas img), el navegador solicitará las imágenes. Eso no es bueno.
douyw
592
myString.replace(/<[^>]*>?/gm, '');
nickf
fuente
44
No funciona <img src=http://www.google.com.kh/images/srpr/nav_logo27.png onload="alert(42)" si está inyectando document.writeo concatenando con una cadena que contiene un >antes de inyectar vía innerHTML.
Mike Samuel
1
@PerishableDave, estoy de acuerdo en que >quedará en el segundo. Sin embargo, eso no es un riesgo de inyección. El peligro se produce debido a la <izquierda en el primero, lo que hace que el analizador HTML esté en un contexto distinto del estado de los datos cuando se inicia el segundo. Tenga en cuenta que no hay transición del estado de datos en adelante >.
Mike Samuel
73
@ MikeSamuel ¿Ya decidimos esta respuesta? Usuario ingenuo aquí listo para copiar y pegar.
Ziggy
1
Esto también, creo, se confunde por completo si se le da algo como <button onClick="dostuff('>');"></button>Asumir HTML correctamente escrito, aún debe tener en cuenta que un signo mayor podría estar en algún lugar del texto citado en un atributo. También querrás eliminar todo el texto dentro de las <script>etiquetas, al menos.
Jonathon
15
@AntonioMax, he respondido esta pregunta hasta la saciedad , pero en lo esencial de su pregunta, porque el código crítico de seguridad no debe copiarse ni pegarse. Debe descargar una biblioteca y mantenerla actualizada y parcheada para estar seguro contra vulnerabilidades descubiertas recientemente y ante cambios en los navegadores.
Mike Samuel
249

La forma más simple:

jQuery(html).text();

Eso recupera todo el texto de una cadena de HTML.

marca
fuente
111
Siempre usamos jQuery para proyectos, ya que invariablemente nuestros proyectos tienen mucho Javascript. Por lo tanto no añaden volumen, nos aprovechamos de código API existente ...
Marcos
32
Lo usas, pero el OP puede que no. la pregunta era sobre Javascript NO JQuery.
Demencial
105
Sigue siendo una respuesta útil para las personas que necesitan hacer lo mismo que el OP (como yo) y no les importa usar jQuery (como yo), sin mencionar que podría haber sido útil para el OP si estuvieran considerando usar jQuery. El objetivo del sitio es compartir el conocimiento. Tenga en cuenta que el efecto escalofriante que podría tener al castigar respuestas útiles sin una buena razón.
acjay
27
@Dementic sorprendentemente, creo que los hilos con múltiples respuestas son los más útiles, porque a menudo una respuesta secundaria satisface mis necesidades exactas, mientras que la respuesta primaria cumple con el caso general.
Eric Goldberg
36
Eso no funcionará si alguna parte de la cadena no está envuelta en una etiqueta html. por ejemplo, "<b> Error: </b> Ingrese un correo electrónico válido" solo devolverá "Error:"
Aamir Afridi
128

Me gustaría compartir una versión editada de la respuesta aprobada del Shog9 .


Como Mike Samuel señaló con un comentario, esa función puede ejecutar códigos JavaScript en línea.
Pero Shog9 tiene razón cuando dice "deja que el navegador lo haga por ti ..."

entonces ... aquí mi versión editada, usando DOMParser :

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

aquí el código para probar el javascript en línea:

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

Además, no solicita recursos en análisis (como imágenes)

strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
Sabaz
fuente
3
Vale la pena agregar que esta solución solo funciona en el navegador.
kris_IV
1
Esto no son etiquetas de tira, sino más bien PHP htmlspecialchars (). Sigue siendo útil para mí.
Daantje
Tenga en cuenta que esto también elimina los espacios en blanco desde el comienzo del texto.
Raine Revere
También para tener en cuenta, esto funciona en Web Workers
Chris Seufert
Esto parece ser mucho más rápido que la respuesta de @ Shog9
Shmuel Kamensky,
55

Como una extensión del método jQuery, si su cadena podría no contener HTML (por ejemplo, si está tratando de eliminar HTML de un campo de formulario)

jQuery(html).text();`

devolverá una cadena vacía si no hay HTML

Utilizar:

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

en lugar.

Actualización: Como se ha señalado en los comentarios, en algunas circunstancias esta solución ejecutará javascript contenido dentro htmlsi el htmlatacante puede influir en el valor de , use una solución diferente.

user999305
fuente
12
O$("<p>").html(html).text();
Dimitar Dimitrov
44
Esto todavía ejecuta código probablemente peligrosojQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
Simon
pruebe jQuery ("aa & # X003c; script> alert (1) & # X003c; / script> a"). text ();
Grzegorz Kaczan
41

Conversión de HTML para correo electrónico de texto sin formato manteniendo intactos los hipervínculos (un href)

La función anterior publicada por hypoxide funciona bien, pero buscaba algo que básicamente convirtiera HTML creado en un editor de texto enriquecido web (por ejemplo, FCKEditor) y borrara todo HTML, pero dejara todos los enlaces porque quería tanto el HTML como la versión de texto sin formato para ayudar a crear las partes correctas para un correo electrónico STMP (HTML y texto sin formato).

Después de un largo tiempo de búsqueda en Google, a mí y a mis colegas se les ocurrió usar el motor de expresiones regulares en 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, "");

La strvariable comienza así:

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>

y luego de que el código se haya ejecutado se ve así

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 puede ver, todo el HTML se ha eliminado y el enlace se ha perseverado con el texto hipervinculado todavía está intacto. También he reemplazado las etiquetas <p>y <br>con \n(newline char) para que se haya retenido algún tipo de formato visual.

Para cambiar el formato del enlace (p. Ej. BBC (Link->http://www.bbc.co.uk)) Simplemente edite $2 (Link->$1), donde $1está la URL / URI href y el $2texto hipervinculado. Con los enlaces directamente en el cuerpo del texto plano, la mayoría de los clientes de correo SMTP los convierten para que el usuario pueda hacer clic en ellos.

Espero que encuentres esto útil.

Jibberboy2000
fuente
No maneja "& nbsp;"
Rose Nettoyeur el
33

Una mejora a la respuesta aceptada.

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

De esta manera, algo así no hará daño:

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

Firefox, Chromium y Explorer 9+ son seguros. Opera Presto sigue siendo vulnerable. Además, las imágenes mencionadas en las cadenas no se descargan en Chromium y Firefox guardando solicitudes http.

Janghou
fuente
Esto es parte del camino, pero no está a salvo de<script><script>alert();
Arth
1
Eso no ejecuta ningún script aquí en Chromium / Opera / Firefox en Linux, entonces, ¿por qué no es seguro?
Janghou
Mis disculpas, debo haber probado mal, probablemente olvidé hacer clic en ejecutar nuevamente en jsFiddle.
Arth
El argumento "Nuevo" es superfluo, creo?
Jon Schneider
Según las especificaciones , hoy en día es opcional, pero no siempre fue así.
Janghou
23

Esto debería hacer el trabajo en cualquier entorno Javascript (NodeJS incluido).

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
fuente
@pstanton, ¿podría dar un ejemplo práctico de su declaración?
Karl.S
3
<html><style..>* {font-family:comic-sans;}</style>Some Text</html>
pstanton
@pstanton He arreglado el código y agregado comentarios, perdón por la respuesta tardía.
Karl.S
16

Alteré la respuesta de Jibberboy2000 para incluir varios <BR />formatos de etiquetas, retire todo el interior <SCRIPT>y <STYLE>las etiquetas, formatear el HTML resultante mediante la eliminación de múltiples saltos de línea y espacios y convertir algo de código HTML codificada en normal. Después de algunas pruebas, parece que puede convertir la mayoría de las páginas web completas en texto simple donde se retienen el título y el contenido de la página.

En el ejemplo simple,

<!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>

se convierte

Este es mi titulo

Esta cadena tiene código html que quiero eliminar

En esta línea se menciona BBC ( http://www.bbc.co.uk ) con enlace.

Ahora de vuelta al "texto normal" y cosas usando

La función de JavaScript y la página de prueba se ven así:

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;
}

Fue utilizado con 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
fuente
1
Me gusta esta solución porque tiene un tratamiento de caracteres especiales html ... pero aún no es suficiente ... la mejor respuesta para mí sería tratar con todos ellos. (que es probablemente lo que hace jquery).
Daniel Gerson
2
Creo que /<p.*>/gidebería ser /<p.*?>/gi.
cbron
Tenga en cuenta que para eliminar todas las <br>etiquetas que podría usar una buena expresión regular en su lugar: /<br\s*\/?>/de esa manera usted tiene sólo una sustitución en lugar de 3. También me parece que a excepción de la decodificación de las entidades puede tener una sola expresión regular, algo como esto: /<[a-z].*?\/?>/.
Alexis Wilke
Buen guión. Pero, ¿qué pasa con el contenido de la tabla? ¿Alguna idea de cómo se puede mostrar?
Hristo Enev
@DanielGerson, la codificación de HTML se vuelve muy complicada, muy rápida, pero el mejor enfoque parece ser usar la biblioteca
he
15
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");

Esta es una versión regex, que es más resistente a HTML con formato incorrecto, como:

Etiquetas no cerradas

Some text <img

"<", ">" dentro de los atributos de la etiqueta

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

Newlines

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

El 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
fuente
7

Otra solución, sin duda menos elegante que la de nickf o Shog9, sería recorrer recursivamente el DOM comenzando en la etiqueta <body> y agregar cada nodo 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
fuente
3
yikes si vas a crear un árbol DOM a partir de tu cadena, ¡solo usa shog's way!
nickf
Sí, mi solución maneja un mazo donde un martillo normal es más apropiado :-). Y estoy de acuerdo en que las soluciones suyas y de Shog9 son mejores, y básicamente lo dije en la respuesta. Tampoco pude reflejar en mi respuesta que el html ya está contenido en una cadena, lo que hace que mi respuesta sea esencialmente inútil con respecto a la pregunta original de todos modos. :-(
Bryan
1
Para ser justos, esto tiene valor: si absolutamente debe preservar / todo / del texto, entonces tiene al menos una oportunidad decente para capturar nuevas líneas, pestañas, retornos de carro, etc. De nuevo, la solución de nickf debería hacer lo mismo , y mucho más rápido ... eh.
Shog9
7

Si desea mantener los enlaces y la estructura del contenido (h1, h2, etc.), debe consultar TextVersionJS . Puede usarlo con cualquier HTML, aunque se creó para convertir un correo electrónico HTML a texto sin formato.

El uso es muy simple. Por ejemplo en node.js:

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

var textVersion = createTextVersion(yourHtml);

O en el navegador con 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>

También funciona con 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
fuente
4

Después de probar todas las respuestas mencionadas, la mayoría, si no todas, tenían casos extremos y no podían satisfacer completamente mis necesidades.

Comencé a explorar cómo lo hace php y encontré la lib php.js que replica el método strip_tags aquí: http://phpjs.org/functions/strip_tags/

Deminetix
fuente
Esta es una función ordenada y bien documentada. Sin embargo, puede hacerse más rápido cuando allowed == ''creo que es lo que solicitó el OP, que es casi lo que Byron respondió a continuación (Byron solo se [^>]equivocó)
Alexis Wilke
1
Si usa el allowedparámetro, es vulnerable a XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')regresa<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('');
}

Cuentas para> atributos internos y <img onerror="javascript">en elementos dom recién creados.

uso:

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

manifestación:

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

demostración de la respuesta superior haciendo las cosas terribles:

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

usuario40521
fuente
También deberá manejar las comillas escapadas dentro de un valor de atributo (por ejemplo string with <a malicious="attribute \">this text should be removed, but is not">example</a>).
Recogida de Logan el
4

Mucha gente ya ha respondido esto, pero pensé que podría ser útil compartir la función que escribí que quita las etiquetas HTML de una cadena pero le permite incluir una serie de etiquetas que no desea quitar. Es bastante corto y ha estado funcionando bien para mí.

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
fuente
3

Creo que la forma más fácil es usar expresiones regulares como alguien mencionado anteriormente. Aunque no hay razón para usar un montón de ellos. Tratar:

stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
Byron Carasco
fuente
11
No hagas esto si te importa la seguridad. Si la entrada del usuario es esta: '<scr <script> ipt> alert (42); </ scr </script> ipt>', la versión eliminada será esta: '<script> alert (42); </ script > '. Entonces esta es una vulnerabilidad XSS.
molnarg
Debe cambiar el [^<>]con [^>]porque una etiqueta válida no puede incluir un <carácter, entonces la vulnerabilidad XSS desaparece.
Alexis Wilke
3

Hice algunas modificaciones al script original de Jibberboy2000 Espero que sea útil para alguien

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
fuente
3

Aquí hay una versión que aborda el problema de seguridad 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 "";
   }
}

Tenga en cuenta que devolverá una cadena vacía si el marcado HTML no es XML válido (es decir, las etiquetas deben estar cerradas y los atributos deben estar entre comillas). Esto no es ideal, pero evita el problema de tener el potencial de explotación de seguridad.

Si no es necesario tener un marcado XML válido, puede intentar usar:

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

pero esa no es una solución perfecta tampoco por otras razones.

Jeremy Johnstone
fuente
Eso fallará en muchas circunstancias si el texto proviene de la entrada del usuario (área de texto o widget contento ...)
Alexis Wilke
3

Puede quitar etiquetas html de forma segura utilizando el atributo iframe sandbox .

La idea aquí es que, en lugar de intentar regexificar nuestra cadena, aprovechamos el analizador nativo del navegador al inyectar el texto en un elemento DOM y luego consultar la propiedad textContent/ innerTextde ese elemento.

El elemento más adecuado para inyectar nuestro texto es un iframe de espacio aislado, de esa manera podemos evitar cualquier ejecución de código arbitrario (también conocido como XSS ).

La desventaja de este enfoque es que solo funciona en los navegadores.

Esto es lo que se me ocurrió (no probado en batalla):

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
fuente
¡Gran solución para entornos basados ​​en web! Probablemente no deberías estar usando un IIFE ya que desde ECMAScript 2015, las variables de ámbito de bloque ya tienen un ámbito adecuado para el bloque con los operadores lety const. Además, al usar su solución, obtuve muchas referencias de iframesno utilizadas dentro del documento. Considere agregar un document.body.removeChild(sandbox)código en el futuro para futuros lectores basados ​​en copy-pasta.
Amin NAIRI
2

Con jQuery puedes simplemente recuperarlo usando

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

El siguiente código le permite retener algunas etiquetas html mientras elimina todas las demás

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
fuente
1
Debe citar la fuente ( phpjs). Si usa el allowedparámetro, es vulnerable a XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')regresa<p onclick="alert(1)">mytext</p>
Chris Cinelli
2

También es posible usar el fantástico analizador htmlparser2 pure JS HTML. Aquí hay una demostración funcional:

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('');

La salida será This is a simple example.

Véalo en acción aquí: https://tonicdev.com/jfahrenkrug/extract-text-from-html

Esto funciona tanto en el nodo como en el navegador si empaqueta su aplicación web utilizando una herramienta como webpack.

Johannes Fahrenkrug
fuente
2

Solo necesitaba quitar las <a>etiquetas y reemplazarlas con el texto del enlace.

Esto parece funcionar muy bien.

htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');
FrigginGlorious
fuente
Esto solo se aplica a las etiquetas y necesita ajustes por ser una función amplia.
m3nda
Sí, además de una etiqueta de anclaje podría tener muchos otros atributos como el title="...".
Alexis Wilke
1

Yo mismo he creado una expresión regular de trabajo:

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

jquery simple de 2 líneas para quitar el 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
Desarrollador
fuente
1

La respuesta aceptada funciona bien en su mayoría, sin embargo, en IE, si la htmlcadena se nullobtiene "null"(en lugar de ''). Fijo:

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

Usando Jquery:

function stripTags() {
    return $('<p></p>').html(textToEscape).text()
}
matemáticas2001
fuente
1

inputel elemento admite solo una línea de texto :

El estado del texto representa un control de edición de texto sin formato de una línea para el valor del elemento.

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

Actualización: esto funciona como se esperaba

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
fuente
No funciona, siempre menciona el navegador que estás utilizando al publicar una respuesta. Esto es inexacto y no funcionará en Chrome 61. Las etiquetas solo se representan como una cadena.
vdegenne
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 esto como un complemento jquery y úselo de la siguiente manera:

$.html2text(htmlContent);
Shiv Shankar
fuente
Digamos que esto proviene de la entrada del usuario. Se puede utilizar para agregar secuencias de comandos o macros a su página
Oluwatumbi