Antworten:
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 .
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
myString.replace(/<[^>]*>?/gm, '');
<img src=http://www.google.com.kh/images/srpr/nav_logo27.png onload="alert(42)"
wenn Sie über injizieren document.write
oder mit einer Zeichenfolge verketten, die ein enthält, >
bevor Sie über injizieren innerHTML
.
>
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 >
.
<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 .
Einfachster Weg:
jQuery(html).text();
Dadurch wird der gesamte Text aus einer HTML-Zeichenfolge abgerufen.
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'>")
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, html
wenn der Wert von html
von einem Angreifer beeinflusst werden könnte. Verwenden Sie eine andere Lösung.
$("<p>").html(html).text();
jQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
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 str
Variable 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 $1
sich die href URL / URI und das $2
der 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.
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.
<script><script>alert();
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, '');
<html><style..>* {font-family:comic-sans;}</style>Some Text</html>
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 "normal text" and stuff using <html encoding>
</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(/ /gi," ");
returnText=returnText.replace(/&/gi,"&");
returnText=returnText.replace(/"/gi,'"');
returnText=returnText.replace(/</gi,'<');
returnText=returnText.replace(/>/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 />
/<p.*>/gi
sollte sein /<p.*?>/gi
.
<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].*?\/?>/
.
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, "");
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;
}
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);
});
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/
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.)
allowed
Parameter 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>
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:
string with <a malicious="attribute \">this text should be removed, but is not">example</a>
. B. ).
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>
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, "");
[^<>]
mit ändern, [^>]
da ein gültiges Tag kein <
Zeichen enthalten kann. Dann verschwindet die XSS-Sicherheitsanfälligkeit.
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");
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.
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));
let
und ordnungsgemäß auf den Block festgelegt sind const
. Außerdem habe ich mit Ihrer Lösung viele Referenzen erhalten, die iframes
nicht 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.
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 : '';
});
}
phpjs
) zitieren . Wenn Sie den allowed
Parameter 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>
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.
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, '');
title="..."
.
Versuchen Sie dies zur einfacheren Lösung => https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/
var StrippedString = OriginalString.replace(/(<([^>]+)>)/ig,"");
einfache 2-zeilige Abfrage zum Entfernen des HTML-Codes.
var content = "<p>checking the html source </p><p>
</p><p>with </p><p>all</p><p>the html </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
Die akzeptierte Antwort funktioniert meistens einwandfrei, jedoch im IE, wenn die html
Zeichenfolge lautet, erhalten null
Sie 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 || "";
}
input
Element 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;
}
(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);