HTML aus Text JavaScript entfernen


655

Gibt es eine einfache Möglichkeit, eine HTML-Zeichenfolge in JavaScript zu verwenden und die HTML-Datei zu entfernen?

Antworten:


760

Wenn Sie in einem Browser arbeiten, ist es am einfachsten , den Browser dies für Sie tun zu lassen ...

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

Hinweis: Wie die Leute in den Kommentaren bemerkt haben, wird dies am besten vermieden, wenn Sie die HTML-Quelle nicht kontrollieren (führen Sie dies beispielsweise nicht auf etwas aus, das von Benutzereingaben stammen könnte). Für diese Szenarien können Sie immer noch der Browser lassen , die Arbeit für Sie tun - Saba Antwort auf mit den jetzt weithin verfügbaren DOMParser sehen .


40
Denken Sie daran, dass dieser Ansatz ziemlich inkonsistent ist und bestimmte Zeichen in bestimmten Browsern nicht entfernen kann. In Prototype.js verwenden wir diesen Ansatz beispielsweise für die Leistung,
umgehen

11
Denken Sie daran, dass Ihr Leerzeichen durcheinander gebracht wird. Ich habe diese Methode verwendet und hatte dann Probleme, da bestimmte Produktcodes doppelte Leerzeichen enthielten, die als einzelne Leerzeichen endeten, nachdem ich den innerText vom DIV zurückerhalten hatte. Dann stimmten die Produktcodes später in der Anwendung nicht überein.
Magnus Smith

11
@Magnus Smith: Ja, wenn Leerzeichen ein Problem darstellen - oder wenn Sie wirklich einen Text benötigen, der nicht direkt das spezifische HTML-DOM betrifft, mit dem Sie arbeiten -, ist es besser, eines der anderen zu verwenden hier angegebene Lösungen. Die Hauptvorteile dieser Methode sind, dass sie 1) trivial ist und 2) Tags, Leerzeichen, Entitäten, Kommentare usw. zuverlässig auf dieselbe Weise verarbeitet wie der Browser, in dem Sie ausgeführt werden . Dies ist häufig für Webclient-Code nützlich, jedoch nicht unbedingt für die Interaktion mit anderen Systemen geeignet, bei denen die Regeln unterschiedlich sind.
Shog9

220
Verwenden Sie dies nicht mit HTML aus einer nicht vertrauenswürdigen Quelle. Um zu sehen warum, versuchen Sie zu laufenstrip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Mike Samuel

24
Wenn HTML Bilder enthält (IMG-Tags), werden die Bilder vom Browser angefordert. Das ist nicht gut.
Douyw

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

4
Funktioniert nicht, <img src=http://www.google.com.kh/images/srpr/nav_logo27.png onload="alert(42)" wenn Sie über injizieren document.writeoder mit einer Zeichenfolge verketten, die ein enthält, >bevor Sie über injizieren innerHTML.
Mike Samuel

1
@PerishableDave, ich stimme zu, dass das >in der Sekunde verlassen wird. Das ist jedoch keine Injektionsgefahr. Die Gefahr tritt aufgrund von <left in the first auf, wodurch sich der HTML-Parser beim Start des zweiten in einem anderen Kontext als dem Datenstatus befindet . Beachten Sie, dass es keinen Übergang vom Datenstatus gibt >.
Mike Samuel

73
@ MikeSamuel Haben wir uns schon für diese Antwort entschieden? Naiver Benutzer hier bereit zum Kopieren und Einfügen.
Ziggy

1
Ich glaube auch, dass dies völlig verwirrt ist, wenn man etwas wie <button onClick="dostuff('>');"></button>korrekt geschriebenes HTML annimmt. Sie müssen dennoch berücksichtigen, dass sich möglicherweise ein Zeichen größer als irgendwo im zitierten Text eines Attributs befindet. Außerdem möchten Sie <script>zumindest den gesamten Text in Tags entfernen .
Jonathon

15
@AntonioMax, ich habe diese Frage ad nauseam beantwortet , aber auf den Inhalt Ihrer Frage, da sicherheitskritischer Code nicht kopiert und eingefügt werden sollte. Sie sollten eine Bibliothek herunterladen und auf dem neuesten Stand halten und patchen, damit Sie vor kürzlich entdeckten Sicherheitslücken und Änderungen in Browsern geschützt sind.
Mike Samuel

249

Einfachster Weg:

jQuery(html).text();

Dadurch wird der gesamte Text aus einer HTML-Zeichenfolge abgerufen.


111
Wir verwenden jQuery immer für Projekte, da unsere Projekte immer viel Javascript enthalten. Deshalb haben wir keine Masse hinzugefügt, wir haben den vorhandenen API-Code ausgenutzt ...
Mark

32
Sie verwenden es, das OP jedoch möglicherweise nicht. Die Frage betraf Javascript, NICHT JQuery.
Dementic

105
Es ist immer noch eine nützliche Antwort für Leute, die das Gleiche wie das OP tun müssen (wie ich) und nichts dagegen haben, jQuery (wie ich) zu verwenden, ganz zu schweigen davon, dass es für das OP nützlich gewesen sein könnte, wenn sie darüber nachgedacht hätten, es zu verwenden jQuery. Der Zweck der Website ist es, Wissen zu teilen. Denken Sie daran, dass Sie möglicherweise einen abschreckenden Effekt haben, wenn Sie nützliche Antworten ohne guten Grund züchtigen.
Acjay

27
@Dementic schockierend, ich finde die Threads mit mehreren Antworten am nützlichsten, da oft eine sekundäre Antwort genau meinen Anforderungen entspricht, während die primäre Antwort dem allgemeinen Fall entspricht.
Eric Goldberg

36
Das funktioniert nicht, wenn ein Teil der Zeichenfolge nicht in ein HTML-Tag eingeschlossen ist. zB "<b> Fehler: </ b> Bitte geben Sie eine gültige E-Mail-Adresse ein" gibt nur "Fehler:" zurück
Aamir Afridi

127

Ich möchte eine bearbeitete Version der genehmigten Antwort des Shog9 teilen .


Wie Mike Samuel mit einem Kommentar betonte, kann diese Funktion Inline-Javascript-Codes ausführen.
Aber Shog9 hat Recht, wenn er sagt "Lass den Browser das für dich tun ..."

also .. hier meine bearbeitete Version mit DOMParser :

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

hier der Code zum Testen des Inline-Javascript:

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

Außerdem werden keine Ressourcen zum Analysieren angefordert (wie Bilder).

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

3
Es ist erwähnenswert, dass diese Lösung nur im Browser funktioniert.
kris_IV

1
Dies sind keine Strip-Tags, sondern eher PHP htmlspecialchars (). Immer noch nützlich für mich.
Daantje

Beachten Sie, dass dadurch auch Leerzeichen am Anfang des Textes entfernt werden.
Raine Revere

Zu beachten ist auch, dass dies in Web Workers funktioniert
Chris Seufert

Dies scheint viel schneller zu sein als die Antwort von @ Shog9
Shmuel Kamensky

55

Als Erweiterung der jQuery-Methode, wenn Ihre Zeichenfolge möglicherweise kein HTML enthält (z. B. wenn Sie versuchen, HTML aus einem Formularfeld zu entfernen)

jQuery(html).text();`

gibt eine leere Zeichenfolge zurück, wenn kein HTML vorhanden ist

Verwenden:

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

stattdessen.

Update: Wie in den Kommentaren erwähnt, führt diese Lösung unter bestimmten Umständen Javascript aus, das darin enthalten ist, htmlwenn der Wert von htmlvon einem Angreifer beeinflusst werden könnte. Verwenden Sie eine andere Lösung.


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

4
Dies führt immer noch wahrscheinlich gefährlichen Code ausjQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
Simon

Versuchen Sie es mit jQuery ("aa & # X003c; script> alert (1) & # X003c; / script> a"). text ();
Grzegorz Kaczan

41

Konvertieren von HTML für Nur-Text-E-Mails unter Beibehaltung von Hyperlinks (a href)

Die obige Funktion von Hypoxide funktioniert einwandfrei, aber ich war auf der Suche nach etwas, das im Grunde genommen HTML konvertiert, das in einem Web RichText-Editor (zum Beispiel FCKEditor) erstellt wurde, und alles HTML löscht, aber alle Links belässt, da ich sowohl HTML als auch HTML wollte Die Nur-Text-Version hilft beim Erstellen der richtigen Teile für eine STMP-E-Mail (sowohl HTML als auch Nur-Text).

Nach langer Suche in Google haben ich und meine Kollegen dies mithilfe der Regex-Engine in Javascript gefunden:

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

Die strVariable beginnt folgendermaßen:

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>

und nachdem der Code ausgeführt wurde, sieht er folgendermaßen aus:

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

Wie Sie sehen können, wurde der gesamte HTML-Code entfernt und der Link wurde beibehalten. Der verlinkte Text ist noch intakt. Außerdem habe ich die Tags <p>und <br>durch \n(newline char) ersetzt, damit eine visuelle Formatierung beibehalten wird.

Um das Linkformat (z. B. BBC (Link->http://www.bbc.co.uk)) zu ändern, bearbeiten Sie einfach das $2 (Link->$1), wo $1sich die href URL / URI und das $2der verlinkte Text befindet. Mit den Links direkt im Haupttext konvertieren die meisten SMTP-Mail-Clients diese, sodass der Benutzer auf sie klicken kann.

Ich hoffe, Sie finden das nützlich.


"& Nbsp;"
Rose Nettoyeur

33

Eine Verbesserung der akzeptierten Antwort.

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

Auf diese Weise schadet etwas, das so läuft:

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

Firefox, Chromium und Explorer 9+ sind sicher. Opera Presto ist immer noch anfällig. Auch in den Zeichenfolgen erwähnte Bilder werden in Chromium- und Firefox-Speichern von http-Anforderungen nicht heruntergeladen.


Dies ist ein Teil des Weges dorthin, aber nicht sicher vor<script><script>alert();
Arth

1
Das führt hier in Chromium / Opera / Firefox unter Linux keine Skripte aus. Warum ist es also nicht sicher?
Janghou

Ich entschuldige mich, ich muss es falsch getestet haben, ich habe wahrscheinlich vergessen, auf jsFiddle erneut auf Ausführen zu klicken.
Arth

Das "neue" Argument ist überflüssig, denke ich?
Jon Schneider

Nach den Spezifikationen ist es heutzutage optional, aber nicht immer.
Janghou

23

Dies sollte die Arbeit in jeder Javascript-Umgebung erledigen (einschließlich 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 Könnten Sie ein funktionierendes Beispiel für Ihre Aussage geben?
Karl.S

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

@pstanton Ich habe den Code korrigiert und Kommentare hinzugefügt, entschuldige die verspätete Antwort.
Karl.S

15

Ich habe die Antwort von Jibberboy2000 dahingehend geändert , dass sie mehrere <BR />Tag-Formate enthält, alles darin <SCRIPT>und <STYLE>Tags entfernt, den resultierenden HTML-Code durch Entfernen mehrerer Zeilenumbrüche und Leerzeichen formatiert und HTML-codierten Code in normalen Code konvertiert. Nach einigen Tests scheint es, dass Sie die meisten vollständigen Webseiten in einfachen Text konvertieren können, wobei Seitentitel und Inhalt beibehalten werden.

Im einfachen Beispiel

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

wird

Das ist mein Titel

Diese Zeichenfolge hat HTML-Code, den ich entfernen möchte

In dieser Zeile wird BBC ( http://www.bbc.co.uk ) mit Link erwähnt.

Nun zurück zu "normalem Text" und so weiter

Die JavaScript-Funktion und die Testseite sehen folgendermaßen aus:

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

Es wurde mit diesem HTML verwendet:

<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
Ich mag diese Lösung, weil sie HTML-Sonderzeichen behandelt ... aber immer noch nicht annähernd genug davon ... die beste Antwort für mich würde sich mit allen befassen. (was wahrscheinlich das ist, was jquery tut).
Daniel Gerson

2
Ich denke /<p.*>/gisollte sein /<p.*?>/gi.
cbron

Beachten Sie, dass Sie zum Entfernen aller <br>Tags stattdessen einen guten regulären Ausdruck verwenden können: Auf /<br\s*\/?>/diese Weise haben Sie nur einen Ersatz anstelle von 3. Außerdem scheint es mir, dass Sie außer der Dekodierung von Entitäten einen einzelnen regulären Ausdruck haben können, etwa so : /<[a-z].*?\/?>/.
Alexis Wilke

Schönes Skript. Aber was ist mit Tabelleninhalten? Irgendeine Idee, wie es angezeigt werden kann
Hristo Enev

@ DanielGerson, das Codieren von HTML wird sehr haarig, sehr schnell, aber der beste Ansatz scheint die Verwendung der Bibliothek zu sein
KyleMit

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

Dies ist eine Regex-Version, die gegenüber fehlerhaftem HTML widerstandsfähiger ist, wie z.

Nicht geschlossene Tags

Some text <img

"<", ">" innerhalb von Tag-Attributen

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

Zeilenumbrüche

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

Der Code

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

Eine andere, zugegebenermaßen weniger elegante Lösung als die von Nickf oder Shog9 wäre, das DOM rekursiv beginnend mit dem <body> -Tag zu durchlaufen und jeden Textknoten anzuhängen.

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
Huch. Wenn Sie einen DOM-Baum aus Ihrer Zeichenfolge erstellen möchten, verwenden Sie einfach den Shog-Weg!
Nickf

Ja, meine Lösung verwendet einen Vorschlaghammer, bei dem ein normaler Hammer besser geeignet ist :-). Und ich stimme zu, dass Ihre und Shog9s Lösungen besser sind, und sagte dies im Grunde auch in der Antwort. Ich habe in meiner Antwort auch nicht berücksichtigt, dass das HTML bereits in einer Zeichenfolge enthalten ist, was meine Antwort in Bezug auf die ursprüngliche Frage ohnehin im Wesentlichen unbrauchbar macht. :-(
Bryan

1
Um fair zu sein, hat dies einen Wert - wenn Sie unbedingt den gesamten Text beibehalten müssen, dann hat dies zumindest eine gute Chance, Zeilenumbrüche, Tabulatoren, Wagenrückläufe usw. zu erfassen. Andererseits sollte die Lösung von nickf dasselbe tun und viel schneller machen ... eh.
Shog9

7

Wenn Sie die Links und die Struktur des Inhalts (h1, h2 usw.) beibehalten möchten , sollten Sie TextVersionJS ausprobieren. Sie können es mit jedem HTML- Code verwenden, obwohl es erstellt wurde, um eine HTML-E-Mail in einfachen Text zu konvertieren.

Die Bedienung ist sehr einfach. Zum Beispiel 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);

Oder im Browser mit reinem js:

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

Es funktioniert auch mit 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

Nachdem ich alle Antworten ausprobiert hatte, hatten die meisten, wenn nicht alle Randfälle und konnten meine Bedürfnisse nicht vollständig erfüllen.

Ich begann zu untersuchen, wie PHP es macht und stieß auf die lib von php.js, die die strip_tags-Methode hier repliziert: http://phpjs.org/functions/strip_tags/


Dies ist eine ordentliche Funktion und gut dokumentiert. Es kann jedoch schneller gemacht werden, wenn das, allowed == ''was ich denke, das ist, was das OP verlangt hat, was fast das ist, was Byron unten geantwortet hat (Byron hat nur das [^>]Falsche verstanden.)
Alexis Wilke

1
Wenn Sie den allowedParameter verwenden, sind Sie anfällig für XSS: gibt stripTags('<p onclick="alert(1)">mytext</p>', '<p>')zurück<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('');
}

Berücksichtigt> innerhalb von Attributen und <img onerror="javascript">in neu erstellten dom-Elementen.

Verwendungszweck:

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

Demo:

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

Demo der Top-Antwort für die schrecklichen Dinge:

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


Sie müssen maskierte Anführungszeichen auch innerhalb eines Attributwerts verarbeiten (z string with <a malicious="attribute \">this text should be removed, but is not">example</a>. B. ).
Logan Pickup

4

Viele Leute haben dies bereits beantwortet, aber ich dachte, es könnte nützlich sein, die von mir geschriebene Funktion zu teilen, mit der HTML-Tags aus einer Zeichenfolge entfernt werden, aber Sie können ein Array von Tags einfügen, die nicht entfernt werden sollen. Es ist ziemlich kurz und hat gut für mich funktioniert.

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

Ich denke, der einfachste Weg ist, reguläre Ausdrücke wie oben erwähnt zu verwenden. Obwohl es keinen Grund gibt, ein paar davon zu verwenden. Versuchen:

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

11
Tun Sie dies nicht, wenn Sie Wert auf Sicherheit legen. Wenn die Benutzereingabe wie folgt lautet: '<scr <script> ipt> alert (42); </ scr </ script> ipt>', lautet die gestrippte Version wie folgt: '<script> alert (42); </ script > '. Dies ist also eine XSS-Sicherheitslücke.
Molnarg

Sie sollten das [^<>]mit ändern, [^>]da ein gültiges Tag kein <Zeichen enthalten kann. Dann verschwindet die XSS-Sicherheitsanfälligkeit.
Alexis Wilke

3

Ich habe einige Änderungen am ursprünglichen Jibberboy2000-Skript vorgenommen. Ich hoffe, es ist für jemanden nützlich

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

Hier ist eine Version, die sich mit den Sicherheitsbedenken von @ MikeSamuel befasst:

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

Beachten Sie, dass eine leere Zeichenfolge zurückgegeben wird, wenn das HTML-Markup kein gültiges XML ist (auch bekannt als Tags müssen geschlossen und Attribute in Anführungszeichen gesetzt werden). Dies ist nicht ideal, vermeidet jedoch das Problem, dass die Sicherheit ausgenutzt werden kann.

Wenn Sie kein gültiges XML-Markup benötigen, können Sie Folgendes verwenden:

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

Aber das ist auch aus anderen Gründen keine perfekte Lösung.


Das wird unter vielen Umständen fehlschlagen, wenn der Text von Benutzereingaben stammt (Textbereich oder inhaltsbearbeitbares Widget ...)
Alexis Wilke

3

Sie können HTML-Tags mithilfe des iframe-Sandbox-Attributs sicher entfernen .

Die Idee hier ist, dass wir, anstatt zu versuchen, unsere Zeichenfolge neu zu formulieren, den nativen Parser des Browsers nutzen, indem wir den Text in ein DOM-Element einfügen und dann die textContent/ -Eigenschaft dieses Elements abfragen innerText.

Das am besten geeignete Element zum Einfügen unseres Textes ist ein Sandbox-Iframe. Auf diese Weise können wir jede Ausführung von willkürlichem Code verhindern (auch als XSS bezeichnet ).

Der Nachteil dieses Ansatzes ist, dass er nur in Browsern funktioniert.

Folgendes habe ich mir ausgedacht (nicht kampferprobt):

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

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

Tolle Lösung für webbasierte Umgebungen! Sie sollten wahrscheinlich kein IIFE verwenden, da seit ECMAScript 2015 Variablen mit Blockbereich bereits mit den Operatoren letund ordnungsgemäß auf den Block festgelegt sind const. Außerdem habe ich mit Ihrer Lösung viele Referenzen erhalten, die iframesnicht im Dokument verwendet wurden. Erwägen Sie das Hinzufügen eines document.body.removeChild(sandbox)Codes im Code für zukünftige Leser, die auf Copy-Pasta basieren.
Amin NAIRI

2

Mit jQuery können Sie es einfach mit abrufen

$('#elementID').text()

2

Mit dem folgenden Code können Sie einige HTML-Tags beibehalten, während Sie alle anderen entfernen

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
Sie sollten die Quelle ( phpjs) zitieren . Wenn Sie den allowedParameter verwenden, sind Sie anfällig für XSS: gibt stripTags('<p onclick="alert(1)">mytext</p>', '<p>')zurück<p onclick="alert(1)">mytext</p>
Chris Cinelli

2

Es ist auch möglich, den fantastischen reinen JS-HTML-Parser htmlparser2 zu verwenden . Hier ist eine funktionierende Demo:

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

Die Ausgabe wird sein This is a simple example.

Sehen Sie es hier in Aktion: https://tonicdev.com/jfahrenkrug/extract-text-from-html

Dies funktioniert sowohl im Knoten als auch im Browser, wenn Sie Ihre Webanwendung mit einem Tool wie Webpack packen.


2

Ich musste nur die <a>Tags entfernen und sie durch den Text des Links ersetzen.

Das scheint großartig zu funktionieren.

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

Dies gilt nur für Tags und muss angepasst werden, um eine breite Funktion zu erhalten.
m3nda

Ja, außerdem könnte ein Ankertag viele andere Attribute haben, wie z title="...".
Alexis Wilke


1

Ich habe selbst einen funktionierenden regulären Ausdruck erstellt:

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

1

einfache 2-zeilige Abfrage zum Entfernen des HTML-Codes.

 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

Die akzeptierte Antwort funktioniert meistens einwandfrei, jedoch im IE, wenn die htmlZeichenfolge lautet, erhalten nullSie die "null"(anstelle von ''). Fest:

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

1

Verwenden von Jquery:

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

1

inputElement unterstützt nur einen Zeilentext :

Der Textstatus repräsentiert ein einzeiliges Nur-Text-Bearbeitungssteuerelement für den Wert des Elements.

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

Update: Dies funktioniert wie erwartet

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

Funktioniert nicht, bitte erwähnen Sie immer den Browser, den Sie verwenden, wenn Sie eine Antwort veröffentlichen. Dies ist ungenau und funktioniert in Chrome 61 nicht. Tags werden nur als Zeichenfolge gerendert.
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);

Definieren Sie dies als jquery-Plugin und verwenden Sie es wie folgt:

$.html2text(htmlContent);

Nehmen wir an, dies kommt von Benutzereingaben. Es kann verwendet werden, um Skript oder Makros zu Ihrer Seite
hinzuzufügen
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.