Yanıtlar:
Bir tarayıcıda çalışıyorsanız, en kolay yol tarayıcının sizin için yapmasına izin vermektir ...
function stripHtml(html)
{
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
Not: İnsanların yorumlarda belirttiği gibi, HTML'nin kaynağını kontrol etmezseniz (örneğin, bunu kullanıcı girişinden gelebilecek herhangi bir şeyde çalıştırmayın) en iyi kaçınılmalıdır. Bu senaryolar için şunları yapabilirsiniz hala - Neden tarayıcı çalışma yapalım şimdi çok yaygın kullanılan DOMParser kullanımıyla ilgili Saba'nın cevaba bakınız .
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)"
Aracılığıyla enjeksiyon yapmadan önce document.write
içeren bir dize ile enjekte ediyorsanız veya bu dizeyle birleştiriyorsanız işe yaramaz . >
innerHTML
>
iradenin ikinci olarak bırakacağını kabul ediyorum . Bu bir enjeksiyon tehlikesi değil. Tehlike <
, birincisinde soldan dolayı oluşur ; bu, HTML ayrıştırıcısının , ikinci başlatıldığında veri durumu dışında bir bağlamda olmasına neden olur . Veri durumundan açık geçiş olmadığını unutmayın >
.
<button onClick="dostuff('>');"></button>
doğru yazılmış bir HTML varsayarsak , tamamen bir karışıklık varsa , yine de bir özniteliğin alıntı metninde bir yerde daha büyük bir işaret olabileceğini dikkate almanız gerekir. Ayrıca <script>
, en azından etiketlerin içindeki tüm metni kaldırmak istersiniz .
En basit yol:
jQuery(html).text();
Bu, tüm metni bir html dizesinden alır.
Shog9'un onaylanmış cevabının düzenlenmiş bir versiyonunu paylaşmak istiyorum .
Mike Samuel'in bir yoruma işaret ettiği gibi , bu işlev satır içi javascript kodlarını yürütebilir.
Ama Şok9 , "tarayıcının sizin için yapmasına izin verin ..."
işte DOMParser kullanarak düzenlediğim sürüm :
function strip(html){
var doc = new DOMParser().parseFromString(html, 'text/html');
return doc.body.textContent || "";
}
burada satır içi javascript test kodu:
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Ayrıca, ayrıştırmada kaynak istemez (resimler gibi)
strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
JQuery yönteminin bir uzantısı olarak, dizeniz HTML içermiyorsa (ör. HTML'yi bir form alanından kaldırmaya çalışıyorsanız)
jQuery(html).text();`
HTML yoksa boş bir dize döndürür
kullanın:
jQuery('<p>' + html + '</p>').text();
yerine.
Güncelleme:
As Açıklamalarda belirttiği edilmiş, bazı durumlarda bu çözüm javascript içerdiği çalıştırır içinde html
değeri isehtml
bir saldırganın etkilenebilirse , farklı bir çözüm kullanın.
$("<p>").html(html).text();
jQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
Hipoksit tarafından yayınlanan yukarıdaki işlevi iyi çalışır, ancak temelde bir Web RichText düzenleyicide (örneğin FCKEditor) oluşturulan HTML dönüştürmek ve tüm HTML temizlemek ama hem HTML istedim gerçeği nedeniyle tüm Bağlantılar bırakacak bir şey peşindeydim bir STMP e-postasında doğru bölümlerin oluşturulmasına yardımcı olacak düz metin sürümü (hem HTML hem de düz metin).
Google'da kendimi ve meslektaşlarımı uzun süre aradıktan sonra Javascript'teki regex motorunu kullanarak bunu bulduk:
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, "");
str
Değişken böyle başlar:
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>
ve sonra kod çalıştırdıktan sonra şöyle görünür: -
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
Gördüğünüz gibi tüm HTML kaldırıldı ve Köprü metni ile bağlantı devam etti hala sağlam. Ayrıca <p>
ve <br>
etiketleri ile değiştirdim\n
görsel biçimlendirmeye çeşit geçerli sayıldı böylece (yeni satır Char).
Bağlantı biçimini değiştirmek için (örn. BBC (Link->http://www.bbc.co.uk)
) Düzenleyip $2 (Link->$1)
, nerede $1
href URL / URI ve $2
köprü metindir. Doğrudan düz metnin gövdesindeki bağlantılarla, çoğu SMTP Posta İstemcisi bunları dönüştürür, böylece kullanıcı üzerlerine tıklayabilir.
Umarım bunu faydalı bulursun.
Kabul edilen cevapta bir gelişme.
function strip(html)
{
var tmp = document.implementation.createHTMLDocument("New").body;
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
Bu şekilde çalışan bir şey zarar vermez:
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Firefox, Chromium ve Explorer 9+ güvenlidir. Opera Presto hala savunmasız. Ayrıca dizelerde belirtilen görüntüler Chromium ve Firefox'ta kaydedilen http isteklerini indirmez.
<script><script>alert();
Bu işlem herhangi bir Javascript ortamında (NodeJS dahil) yapılmalıdır.
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>
Jibberboy2000'in cevabını birkaç <BR />
etiket formatı içerecek şekilde değiştirdim , içindeki her şeyi kaldırın<SCRIPT>
ve<STYLE>
, etiketleri birden satır sonları ve boşlukları kaldırarak elde edilen HTML biçimlendirmek ve normal içine bazı HTML-kodlanmış kod dönüştürün. Bazı testlerden sonra, tam web sayfalarının çoğunu sayfa başlığı ve içeriğinin tutulduğu basit bir metne dönüştürebileceğiniz anlaşılıyor.
Basit örnekte,
<!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>
olur
Bu benim başlığım
Bu dize kaldırmak istediğiniz html kodu var
Bu hatta BBC ( http://www.bbc.co.uk ) belirtilmiştir.
Şimdi geri "normal metin" ve şeyler kullanarak
JavaScript işlevi ve test sayfası şuna benzer:
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;
}
Bu HTML ile kullanıldı:
<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
olmalı /<p.*?>/gi
.
<br>
etiketleri kaldırmak için iyi bir normal ifade kullanabilirsiniz: /<br\s*\/?>/
3 yerine sadece bir yerine sahip olabilirsiniz /<[a-z].*?\/?>/
.
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
Bu, yanlış biçimlendirilmiş HTML'ye daha dirençli bir normal ifade sürümüdür:
Kapatılmamış etiketler
Some text <img
"<", ">" etiket niteliklerinin içinde
Some text <img alt="x > y">
yeni satırların
Some <a
href="http://google.com">
Kod
var html = '<br>This <img alt="a>b" \r\n src="a_b.gif" />is > \nmy<>< > <a>"text"</a'
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
Kuşkusuz, nickf veya Shog9'lardan daha az zarif bir çözüm, <body> etiketinden başlayarak DOM'u tekrar tekrar yürümek ve her metin düğümünü eklemek olacaktır.
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;
}
Bağlantıları ve içeriğin yapısını (h1, h2, vb.) Korumak istiyorsanız, TextVersionJS'yi kontrol etmelisiniz . HTML e-postasını düz metne dönüştürmek için oluşturulmuş olmasına rağmen herhangi bir HTML ile kullanabilirsiniz.
Kullanımı çok basit. Örneğin node.js'de:
var createTextVersion = require("textversionjs");
var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
var textVersion = createTextVersion(yourHtml);
Veya tarayıcıda saf js ile:
<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>
Ayrıca requir.js ile çalışır:
define(["textversionjs"], function(createTextVersion) {
var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
var textVersion = createTextVersion(yourHtml);
});
Tüm cevapları denedikten sonra hepsinde en son vakalar olmasa da en çok bahsedilen cevaplar vardı ve ihtiyaçlarımı tamamen destekleyemedi.
Ben php nasıl yaptığını keşfetmek başladı ve burada strip_tags yöntemi çoğaltır php.js lib rastlamak: http://phpjs.org/functions/strip_tags/
allowed == ''
OP'nin ne istediğini düşündüğümde daha hızlı yapılabilir , bu neredeyse Byron'un aşağıda cevapladığı şeydir (Byron sadece [^>]
yanlış anladı .)
allowed
Param kullanırsanız, XSS'ye karşı savunmasızsınız: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')
döner<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('');
}
İç özellikler ve <img onerror="javascript">
yeni oluşturulan dom öğelerinde hesaplar .
kullanımı:
clean_string = stripHTML("string with <html> in it")
demo:
https://jsfiddle.net/gaby_de_wilde/pqayphzd/
korkunç şeylerin üst yanıt demo:
string with <a malicious="attribute \">this text should be removed, but is not">example</a>
) çıkış karakterleri de kullanmanız gerekir.
Bir çok insan bunu zaten yanıtladı, ancak yazdığım işlevi bir dizeden HTML etiketlerini kesen ancak soyulmasını istemediğiniz bir dizi etiket eklemenize izin vermenin yararlı olabileceğini düşündüm. Oldukça kısa ve benim için iyi çalışıyor.
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>
Bence en kolay yol Düzenli İfadeleri yukarıda bahsedilen biri olarak kullanmaktır. Bir demet kullanmak için bir neden olmasa da. Deneyin:
stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
[^<>]
ile değiştirmelisiniz , ardından XSS güvenlik açığı ortadan kalkar. [^>]
<
Orijinal Jibberboy2000 betiğinde bazı değişiklikler yaptım Umarım birisi için yararlı olur
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");
Sorta'nın @ MikeSamuel'in güvenlik sorununu ele alan bir sürüm:
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 "";
}
}
HTML işaretlemesi geçerli XML değilse boş bir dize döndürür (diğer bir deyişle, etiketlerin kapatılması ve niteliklerin alıntılanması gerekir). Bu ideal değildir, ancak güvenlik yararlanma potansiyeline sahip olma sorununu önler.
Geçerli XML işaretlemesine sahip olmak sizin için bir gereklilikse, aşağıdakileri kullanmayı deneyebilirsiniz:
var doc = document.implementation.createHTMLDocument("");
ancak bu başka nedenlerle de mükemmel bir çözüm değildir.
İframe korumalı alan özniteliğini kullanarak html etiketlerini güvenle kaldırabilirsiniz .
Buradaki fikir, dizemizi yeniden düzenlemeye çalışmak yerine, metni bir DOM öğesine enjekte ederek ve ardından o öğenin textContent
/ innerText
özelliğini sorgulayarak tarayıcının yerel ayrıştırıcısından faydalanmamızdır .
Metnimizi enjekte etmek için en uygun öğe korumalı alanlı iframe'dir, böylece herhangi bir rastgele kod yürütülmesini önleyebiliriz ( XSS olarak da bilinir ).
Bu yaklaşımın dezavantajı, yalnızca tarayıcılarda çalışmasıdır.
İşte (Savaşta test edilmedi):
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 || "";
};
})();
Kullanım ( 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
ve const
işleçleriyle bloğa düzgün bir şekilde dahil edildiğinden, muhtemelen bir IIFE kullanmamalısınız . Ayrıca, çözümünüzü kullanarak iframes
, belgenin içinde kullanılmayan birçok referansım var . document.body.removeChild(sandbox)
Gelecekteki kopya makarna tabanlı okuyucular için koda bir kod eklemeyi düşünün .
Aşağıdaki kod, tüm diğerlerini sıyırırken bazı html etiketlerini korumanıza izin verir
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
) alıntılamalısınız . Eğer kullanırsanız allowed
param size XSS'e şunlardır: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')
getiriler<p onclick="alert(1)">mytext</p>
Fantastik htmlparser2 saf JS HTML ayrıştırıcısını kullanmak da mümkündür . İşte çalışan bir 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('');
Çıktı This is a simple example.
Burada iş başında görün: https://tonicdev.com/jfahrenkrug/extract-text-from-html
Web uygulamasını web paketi gibi bir araç kullanarak paketlerseniz, bu hem düğümde hem de tarayıcıda çalışır.
Sadece <a>
etiketleri soyup bağlantı metniyle değiştirmem gerekiyordu.
Bu harika çalışıyor gibi görünüyor.
htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');
title="..."
.
Daha kolay bir çözüm için şunu deneyin => https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/
var StrippedString = OriginalString.replace(/(<([^>]+)>)/ig,"");
html şerit için basit 2 satır jquery.
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
input
öğe yalnızca bir satır metnini destekler :
Metin durumu, öğenin değeri için tek satırlık düz metin düzenleme denetimini temsil eder.
function stripHtml(str) {
var tmp = document.createElement('input');
tmp.value = str;
return tmp.value;
}
Güncelleme: beklendiği gibi çalışıyor
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);
Bunu bir jquery eklentisi olarak tanımlayın ve aşağıdaki gibi kullanın:
$.html2text(htmlContent);