Rimuovi HTML da JavaScript di testo


656

C'è un modo semplice per prendere una stringa di HTML in JavaScript e rimuovere HTML?

Risposte:


763

Se stai utilizzando un browser, il modo più semplice è lasciare che il browser lo faccia per te ...

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

Nota: come hanno notato le persone nei commenti, è meglio evitarlo se non si controlla l'origine dell'HTML (ad esempio, non eseguirlo su qualcosa che potrebbe provenire dall'input dell'utente). Per quegli scenari, puoi comunque lasciare che il browser faccia il lavoro per te - vedi la risposta di Saba sull'uso del DOMParser ora ampiamente disponibile .


40
Basta ricordare che questo approccio è piuttosto incoerente e non riuscirà a rimuovere determinati caratteri in alcuni browser. Ad esempio, in Prototype.js, utilizziamo questo approccio per le prestazioni, ma
aggiriamo

11
Ricorda che il tuo spazio bianco sarà incasinato. Ho usato questo metodo, e poi ho avuto problemi in quanto alcuni codici prodotto contenevano doppi spazi, che sono diventati spazi singoli dopo aver ottenuto il testo interno dal DIV. Quindi i codici prodotto non si sono adattati successivamente nell'applicazione.
Magnus Smith,

11
@Magnus Smith: Sì, se lo spazio bianco è un problema - o davvero, se hai bisogno di questo testo che non coinvolge direttamente il DOM HTML specifico con cui stai lavorando - allora è meglio usare uno degli altri soluzioni fornite qui. I principali vantaggi di questo metodo sono che è 1) banale e 2) elaborerà in modo affidabile tag, spazi bianchi, entità, commenti, ecc. Allo stesso modo del browser in cui stai eseguendo . Ciò è spesso utile per il codice client Web, ma non è necessariamente appropriato per interagire con altri sistemi in cui le regole sono diverse.
Shog9,

220
Non utilizzare questo con HTML da una fonte non attendibile. Per capire perché, prova a correrestrip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Mike Samuel,

24
Se html contiene immagini (tag img), le immagini verranno richieste dal browser. Questo non è buono.
Douyw,

592
myString.replace(/<[^>]*>?/gm, '');

4
Non funziona <img src=http://www.google.com.kh/images/srpr/nav_logo27.png onload="alert(42)" se stai iniettando via document.writeo concatenando una stringa che contiene un >prima di iniettare via innerHTML.
Mike Samuel,

1
@PerishableDave, sono d'accordo sul fatto che >sarà lasciato nel secondo. Questo non è un rischio di iniezione però. Il pericolo si verifica a causa della <sinistra nel primo, che fa sì che il parser HTML si trovi in ​​un contesto diverso dallo stato dei dati all'avvio del secondo. Nota che non c'è transizione dallo stato dei dati in poi >.
Mike Samuel,

73
@MikeSamuel Abbiamo deciso ancora su questa risposta? Utente ingenuo qui pronto per copiare e incollare.
Ziggy

1
Anche questo, credo, si confonde completamente se dato qualcosa come <button onClick="dostuff('>');"></button>Assumendo un HTML scritto correttamente, devi ancora tener conto del fatto che un segno maggiore di potrebbe essere da qualche parte nel testo citato in un attributo. Inoltre, dovresti rimuovere tutto il testo all'interno dei <script>tag, almeno.
Jonathon,

15
@AntonioMax, ho risposto a questa domanda fino alla nausea , ma alla sostanza della tua domanda, perché il codice critico per la sicurezza non dovrebbe essere copiato e incollato. Dovresti scaricare una libreria, tenerla aggiornata e patchata in modo da essere al sicuro dalle vulnerabilità scoperte di recente e dalle modifiche nei browser.
Mike Samuel,

249

Il modo più semplice:

jQuery(html).text();

Ciò recupera tutto il testo da una stringa di HTML.


111
Usiamo sempre jQuery per i progetti poiché invariabilmente i nostri progetti hanno molto Javascript. Pertanto non abbiamo aggiunto massa, abbiamo sfruttato il codice API esistente ...
Segna il

32
Lo usi, ma l'OP potrebbe non farlo. la domanda riguardava Javascript NON JQuery.
Demenza

105
È ancora una risposta utile per le persone che hanno bisogno di fare la stessa cosa dell'OP (come me) e non si preoccupano di usare jQuery (come me), per non parlare del fatto che avrebbe potuto essere utile all'OP se stessero considerando di usare jQuery. Il punto del sito è condividere le conoscenze. Tieni presente che l'effetto agghiacciante che potresti avere castigando risposte utili senza una buona ragione.
sabato

27
@Dementic in modo scioccante, trovo che i thread con risposte multiple siano i più utili, perché spesso una risposta secondaria soddisfa i miei bisogni esatti, mentre la risposta primaria soddisfa il caso generale.
Eric Goldberg,

36
Ciò non funzionerà se una parte della stringa non è racchiusa nel tag html. ad es. "<b> Errore: </b> inserisci un indirizzo email valido" restituirà solo "Errore:"
Aamir Afridi

128

Vorrei condividere una versione modificata della risposta approvata da Shog9 .


Come ha sottolineato Mike Samuel con un commento, quella funzione può eseguire codici javascript in linea.
Ma Shog9 ragione quando dice "lascia che il browser lo faccia per te ..."

quindi .. qui la mia versione modificata, usando DOMParser :

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

qui il codice per testare il javascript inline:

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

Inoltre, non richiede risorse all'analisi (come le immagini)

strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")

3
Vale la pena aggiungere che questa soluzione funziona solo nel browser.
kris_IV,

1
Non si tratta di strip tag, ma più simili a PHP htmlspecialchars (). Ancora utile per me.
Daantje,

Nota che ciò rimuove anche gli spazi bianchi dall'inizio del testo.
Raine Revere,

Inoltre, questo funziona in Web Workers
Chris Seufert,

Questo sembra essere molto più veloce della risposta di @ Shog9
Shmuel Kamensky,

55

Come estensione del metodo jQuery, se la tua stringa potrebbe non contenere HTML (ad esempio se stai provando a rimuovere HTML da un campo modulo)

jQuery(html).text();`

restituirà una stringa vuota se non c'è HTML

Uso:

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

anziché.

Aggiornamento: Come è stato sottolineato nei commenti, in alcune circostanze questa soluzione eseguirà javascript contenuto all'interno htmlse il valore di htmlpotrebbe essere influenzato da un utente malintenzionato, utilizzare una soluzione diversa.


12
Oppure$("<p>").html(html).text();
Dimitar Dimitrov,

4
Questo esegue ancora probabilmente un codice pericolosojQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
Simon,

prova jQuery ("aa & # X003c; script> alert (1) & # X003c; / script> a"). text ();
Grzegorz Kaczan,

41

Conversione di HTML per e-mail in testo normale mantenendo intatti i collegamenti ipertestuali (a href)

La funzione di cui sopra pubblicata da hypoxide funziona bene, ma stavo cercando qualcosa che convertisse sostanzialmente l'HTML creato in un editor Web RichText (ad esempio FCKEditor) e cancellasse tutto l'HTML, lasciando tutti i collegamenti a causa del fatto che volevo sia l'HTML che il la versione in testo normale per facilitare la creazione delle parti corrette in un'e-mail STMP (sia HTML che testo semplice).

Dopo un lungo periodo di ricerche su Google, me stesso e i miei colleghi hanno scoperto questo usando il motore regex in 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 strvariabile inizia così:

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 dopo che il codice è stato eseguito appare così: -

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

Come puoi vedere, tutto l'HTML è stato rimosso e il collegamento è stato perseverato con il testo con collegamento ipertestuale ancora intatto. Inoltre ho sostituito i tag <p>e <br>con\n (newline char) in modo che sia stata mantenuta una sorta di formattazione visiva.

Per cambiare il formato del collegamento (es. BBC (Link->http://www.bbc.co.uk)) Basta modificare $2 (Link->$1), dove si $1trova l'URL / URI href e il $2testo è il collegamento ipertestuale. Con i collegamenti direttamente nel corpo del testo normale, la maggior parte dei client di posta SMTP li converte in modo che l'utente abbia la possibilità di fare clic su di essi.

Spero che lo trovi utile.


Non gestisce "& nbsp;"
Rose Nettoyeur,

33

Un miglioramento alla risposta accettata.

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

In questo modo qualcosa in esecuzione in questo modo non farà alcun danno:

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

Firefox, Chromium ed Explorer 9+ sono sicuri. Opera Presto è ancora vulnerabile. Anche le immagini menzionate nelle stringhe non vengono scaricate in Chromium e Firefox salvando le richieste http.


Questo è in qualche modo lì, ma non è al sicuro da<script><script>alert();
Arth

1
Questo non esegue script qui in Chromium / Opera / Firefox su Linux, quindi perché non è sicuro?
Janghou,

Mi scuso, devo aver fallito il test, probabilmente ho dimenticato di fare clic di nuovo su jsFiddle.
Arth,

L'argomento "Nuovo" è superfluo, penso?
Jon Schneider,

Secondo le specifiche è facoltativo al giorno d'oggi, ma non è stato sempre.
Janghou,

23

Questo dovrebbe funzionare in qualsiasi ambiente Javascript (incluso NodeJS).

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

@pstanton potresti dare un esempio funzionante della tua affermazione?
Karl.S,

3
<html><style..>* {font-family:comic-sans;}</style>Some Text</html>
Pstanton,

@pstanton Ho corretto il codice e aggiunto commenti, scusate la risposta tardiva.
Karl.S,

16

Ho modificato la risposta di Jibberboy2000 per includere diversi <BR />formati di tag, rimuovere tutto all'interno <SCRIPT>e<STYLE> tag, formattare l'HTML risultante rimuovendo più interruzioni di riga e spazi e convertendo un codice con codice HTML in normale. Dopo alcuni test sembra che sia possibile convertire la maggior parte delle pagine Web complete in testo semplice in cui vengono conservati il ​​titolo e il contenuto della pagina.

Nel semplice esempio,

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

diventa

Questo è il mio titolo

Questa stringa ha un codice HTML che voglio rimuovere

In questa linea viene menzionata la BBC ( http://www.bbc.co.uk ) con link.

Ora torniamo al "testo normale" e roba usando

La funzione JavaScript e la pagina di test sono:

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

È stato usato con questo 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 />

1
Mi piace questa soluzione perché ha il trattamento di caratteri speciali html ... ma non ancora abbastanza di loro ... la migliore risposta per me avrebbe a che fare con tutti loro. (che è probabilmente ciò che fa jquery).
Daniel Gerson,

2
Penso che /<p.*>/gidovrebbe essere /<p.*?>/gi.
cbron,

Si noti che per rimuovere tutti <br>i tag si potrebbe usare una buona espressione regolare invece: /<br\s*\/?>/in questo modo si dispone di un solo sostituire invece di 3. Inoltre mi sembra che, a parte la decodifica delle entità si può avere un unico regex, qualcosa di simile a questo: /<[a-z].*?\/?>/.
Alexis Wilke,

Bella sceneggiatura. Ma per quanto riguarda il contenuto della tabella? Qualche idea su come possa essere visualizzata
Hristo Enev,

@DanielGerson, la codifica html diventa molto pelosa, molto veloce, ma l' approccio migliore sembra usare la libreria
he

15
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");

Questa è una versione regex, che è più resistente all'HTML malformato, come:

Tag non chiusi

Some text <img

"<", ">" all'interno degli attributi del tag

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

newlines

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

Il codice

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

7

Un'altra soluzione, sicuramente meno elegante di quella di nickf o Shog9, sarebbe quella di ricorrere in modo ricorsivo al DOM partendo dal tag <body> e aggiungendo ciascun nodo di testo.

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

3
yikes. se hai intenzione di creare un albero DOM dalla tua stringa, usa semplicemente lo shog!
nickf

Sì, la mia soluzione utilizza un martello in cui un martello normale è più appropriato :-). E sono d'accordo sul fatto che le tue soluzioni di Shog9 e quelle migliori siano, e sostanzialmente lo hanno detto nella risposta. Inoltre non sono riuscito a riflettere nella mia risposta che l'html è già contenuto in una stringa, rendendo comunque la mia risposta essenzialmente inutile per quanto riguarda la domanda originale. :-(
Bryan

1
Per essere onesti, questo ha valore - se devi assolutamente preservare / tutto / del testo, allora questo ha almeno una buona dose nel catturare nuove righe, tabulazioni, ritorni a capo, ecc ... Quindi, di nuovo, la soluzione di Nickf dovrebbe fare lo stesso e fai molto più velocemente ... eh.
Shog9,

7

Se vuoi mantenere i collegamenti e la struttura del contenuto (h1, h2, ecc.) Allora dovresti dare un'occhiata a TextVersionJS Puoi usarlo con qualsiasi HTML, anche se è stato creato per convertire una e-mail HTML in testo semplice.

L'utilizzo è molto semplice. Ad esempio in 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 nel browser 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>

Funziona anche 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);
});

4

Dopo aver provato tutte le risposte menzionate di più, se non tutte hanno avuto casi limite e non sono state in grado di supportare completamente le mie esigenze.

Ho iniziato a esplorare come funziona php e ho trovato la lib php.js che replica il metodo strip_tags qui: http://phpjs.org/functions/strip_tags/


Questa è una funzione chiara e ben documentata. Tuttavia, può essere reso più veloce quando allowed == ''penso che sia ciò che l'OP ha richiesto, il che è quasi ciò che Byron ha risposto di seguito (Byron ha solo [^>]sbagliato.)
Alexis Wilke,

1
Se usi il allowedparametro sei vulnerabile a XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')restituisce<p onclick="alert(1)">mytext</p>
Chris Cinelli il

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

Conta per> attributi interni e <img onerror="javascript">in elementi dom appena creati.

utilizzo:

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

demo:

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

demo della risposta migliore facendo le cose terribili:

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


Dovrai gestire anche le virgolette di escape all'interno di un valore di attributo (ad es string with <a malicious="attribute \">this text should be removed, but is not">example</a>.).
Logan Pickup,

4

Molte persone hanno già risposto a questa domanda, ma ho pensato che potesse essere utile condividere la funzione che ho scritto che spoglia tag HTML da una stringa ma ti consente di includere un array di tag che non vuoi eliminare. È piuttosto corto e ha funzionato bene per me.

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>

3

Penso che il modo più semplice sia usare le espressioni regolari come qualcuno sopra menzionato. Anche se non c'è motivo di usarne un sacco. Provare:

stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");

11
Non farlo se ti interessa la sicurezza. Se l'input dell'utente è questo: '<scr <script> ipt> alert (42); </ scr </script> ipt>', la versione eliminata sarà questa: '<script> alert (42); </ script >'. Quindi questa è una vulnerabilità XSS.
molnarg,

Dovresti cambiare [^<>]con [^>]perché un tag valido non può includere un <carattere, quindi la vulnerabilità XSS scompare.
Alexis Wilke,

3

Ho apportato alcune modifiche allo script originale di Jibberboy2000 Spero che possa essere utile per qualcuno

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");

3

Ecco una versione che risolve i problemi di sicurezza di @ 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 "";
   }
}

Nota, restituirà una stringa vuota se il markup HTML non è XML valido (ovvero, i tag devono essere chiusi e gli attributi devono essere quotati). Questo non è l'ideale, ma evita il problema di avere il potenziale di sfruttamento della sicurezza.

Se non hai un markup XML valido è un requisito per te, puoi provare a usare:

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

ma questa non è una soluzione perfetta neanche per altri motivi.


Ciò fallirà in molte circostanze se il testo proviene dall'input dell'utente (textarea o widget contenteditable ...)
Alexis Wilke,

3

Puoi rimuovere in sicurezza i tag html usando l' attributo sandbox iframe .

L'idea qui è che invece di provare a regexare la nostra stringa, sfruttiamo il parser nativo del browser iniettando il testo in un elemento DOM e quindi interrogando la proprietà textContent/ innerTextdi tale elemento.

L'elemento più adatto in cui iniettare il nostro testo è un iframe sandbox, in questo modo possiamo impedire qualsiasi esecuzione di codice arbitrario (noto anche come XSS ).

L'aspetto negativo di questo approccio è che funziona solo nei browser.

Ecco cosa mi è venuto in mente (non testato in battaglia):

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 || "";
  };
})();

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

Ottima soluzione per ambienti web based! Probabilmente non dovresti usare un IIFE poiché a partire da ECMAScript 2015, le variabili con ambito di blocco sono già comprese correttamente nel blocco con gli operatori lete const. Inoltre, usando la tua soluzione, ho ricevuto molti riferimenti di iframesnon utilizzati all'interno del documento. Prendi in considerazione l'aggiunta di un document.body.removeChild(sandbox)codice nel codice per i futuri lettori basati su copia-pasta.
Amin NAIRI,

2

Con jQuery puoi semplicemente recuperarlo usando

$('#elementID').text()

2

Il codice seguente ti consente di conservare alcuni tag html mentre rimuovi tutti gli altri

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 : '';
      });
}

1
Dovresti citare source ( phpjs). Se usi il allowedparametro sei vulnerabile a XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')restituisce<p onclick="alert(1)">mytext</p>
Chris Cinelli il

2

È anche possibile utilizzare il fantastico htmlparser2 parser HTML puro JS HTML . Ecco una demo funzionante:

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

L'output sarà This is a simple example.

Guardalo in azione qui: https://tonicdev.com/jfahrenkrug/extract-text-from-html

Funziona sia nel nodo che nel browser se impacchetti la tua applicazione web usando uno strumento come il webpack.


2

Avevo solo bisogno di eliminare il <a> tag e sostituirli con il testo del collegamento.

Questo sembra funzionare alla grande.

htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');

Questo vale solo per i tag e deve essere modificato per essere una funzione ampia.
m3nda,

Sì, più un tag anchor potrebbe avere molti altri attributi come il title="...".
Alexis Wilke,


1

Ho creato anch'io un'espressione regolare funzionante:

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

1

semplice jquery a 2 righe per rimuovere l'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

1

La risposta accettata funziona bene soprattutto, tuttavia in IE se la htmlstringa è nullottieni "null"(invece di ''). Fisso:

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

1

Utilizzando Jquery:

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

1

inputl'elemento supporta solo una riga di testo :

Lo stato del testo rappresenta un controllo di modifica del testo in una riga per il valore dell'elemento.

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

Aggiornamento: funziona come previsto

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

Non funziona, si prega di menzionare sempre il browser che si sta utilizzando quando si pubblica una risposta. Questo non è preciso e non funzionerà in Chrome 61. I tag vengono visualizzati come una stringa.
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);

Definisci questo come un plugin jquery e usalo come segue:

$.html2text(htmlContent);

Diciamo che questo deriva dall'input dell'utente. Può essere usato per aggiungere script o macro alla tua pagina
Oluwatumbi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.