Metin JavaScript'ten HTML'yi çıkarın


655

JavaScript'te html dizesi almanın ve html'yi çıkarmanın kolay bir yolu var mı?

Yanıtlar:


761

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 .


40
Sadece bu yaklaşımın tutarsız olduğunu ve belirli tarayıcılarda belirli karakterleri soymayacağını unutmayın. Örneğin, Prototype.js'de bu yaklaşımı performans için kullanıyoruz, ancak bazı eksiklikler üzerinde çalışıyoruz - github.com/kangax/prototype/blob/…
kangax

11
Beyaz alanınızın dağıtılacağını unutmayın. Bu yöntemi kullanıyordum ve daha sonra bazı ürün kodları çift boşluk içerdiğinden, içText'i DIV'den geri aldıktan sonra tek boşluk olarak ortaya çıktığında sorun yaşadım. Daha sonra ürün kodları uygulamada daha sonra eşleşmedi.
Magnus Smith

11
@Magnus Smith: Evet, beyaz alan bir endişe ise - veya gerçekten, doğrudan çalıştığınız HTML DOM'u içermeyen bu metne ihtiyacınız varsa - o zaman diğerinden birini kullanmanız daha iyi olur burada verilen çözümler. Bu yöntemin birincil avantajları, 1) önemsiz olması ve 2) etiketleri, boşlukları, varlıkları, yorumları vb. Çalıştırdığınız tarayıcıyla aynı şekilde güvenilir şekilde işlemek olacaktır . Bu genellikle web istemci kodu için yararlıdır, ancak kuralların farklı olduğu diğer sistemlerle etkileşim kurmak için uygun değildir.
Shog9

220
Bunu güvenilir olmayan bir kaynaktan gelen HTML ile kullanmayın. Nedenini görmek için koşmayı deneyinstrip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Mike Samuel

24
Html resim içeriyorsa (img etiketleri) resimler tarayıcı tarafından istenir. Bu iyi değil.
douyw

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

4
<img src=http://www.google.com.kh/images/srpr/nav_logo27.png onload="alert(42)" Aracılığıyla enjeksiyon yapmadan önce document.writeiçeren bir dize ile enjekte ediyorsanız veya bu dizeyle birleştiriyorsanız işe yaramaz . >innerHTML
Mike Samuel

1
@PerishableDave, >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 >.
Mike Samuel

73
@MikeSamuel Bu yanıta henüz karar verdik mi? Naif kullanıcı burada kopyalayıp yapıştırmaya hazır.
Ziggy

1
Bu da, sanırım, <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 .
Jonathon

15
@AntonioMax, bu soruyu nauseam olarak cevapladım , ancak sorunuzun özüne cevap verdim , çünkü güvenlik kritik kodu kopyalanmamalı ve yapıştırılmamalıdır. Bir kitaplığı indirmeli ve güncel tutmalı ve yakın zamanda keşfedilen güvenlik açıklarına ve tarayıcılardaki değişikliklere karşı güvende olmalısınız.
Mike Samuel

249

En basit yol:

jQuery(html).text();

Bu, tüm metni bir html dizesinden alır.


111
Projelerimizde her zaman jQuery kullanıyoruz, çünkü projelerimizde çok fazla Javascript var. Bu nedenle toplu eklemedik, mevcut API kodundan yararlandık ...
Mark

32
Kullanıyorsunuz, ancak OP olmayabilir. soru Javascript NOT JQuery hakkındaydı.
Dementic

105
OP ile aynı şeyi (benim gibi) yapması gereken ve jQuery (benim gibi) kullanmayı önemsemeyen insanlar için hala yararlı bir cevap, bahsetmiyorum bile, kullanmayı düşünüyorlarsa OP için yararlı olabilirdi jQuery. Sitenin amacı bilgiyi paylaşmaktır. Yararlı yanıtları iyi bir neden olmadan azarlayarak, ürpertici etkinin olabileceğini unutmayın.
Kasım'da acjay

27
@Dementic şok edici bir şekilde, çoklu cevapları olan konuları en yararlı buluyorum, çünkü genellikle ikincil bir cevap kesin ihtiyaçlarımı karşılarken, birincil cevap genel durumu karşılar.
Eric Goldberg

36
Dizenin bir kısmı html etiketine sarılmamışsa bu çalışmaz. örneğin "<b> Hata: </b> Lütfen geçerli bir e-posta girin" yalnızca "Hata:" döndürür
Aamir Afridi

127

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

3
Bu çözümün yalnızca tarayıcıda çalıştığını eklemeye değer.
kris_IV

1
Bu şerit etiketleri değil, daha çok PHP htmlspecialchars () gibidir. Benim için hala yararlı.
Daantje

Bunun, boşlukları metnin başından kaldırdığını da unutmayın.
Raine Revere

Ayrıca, bu Web Çalışanları
Chris Seufert

Bu , @ Shog9'un cevabından çok daha hızlı görünüyor
Shmuel Kamensky

55

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 htmldeğeri isehtml bir saldırganın etkilenebilirse , farklı bir çözüm kullanın.


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

4
Bu hala tehlikeli bir kod yürütüyorjQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
Simon

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

41

Köprüleri (href) olduğu gibi bırakarak Düz Metin e-postası için HTML dönüştürme

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

strDeğ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 $1href URL / URI ve $2kö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.


"& Nbsp;" ile başa çıkmaz
Gül Nettoyeur

33

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.


Bu orada bazı yol, ama güvenli değil<script><script>alert();
Arth

1
Linux'ta Chromium / Opera / Firefox'ta herhangi bir komut dosyası çalıştırmıyor, neden güvenli değil?
Janghou

Özür dilerim, testten kaçmış olmalıyım, muhtemelen jsFiddle'da tekrar çalıştırmayı tıklamayı unuttum.
Arth

"Yeni" argüman gereksiz, sanırım?
Jon Schneider

Göre özellikleri bugünlerde isteğe bağlıdır, ama her zaman değil.
Janghou

23

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

@pstanton ifadenize çalışan bir örnek verebilir misiniz?
Karl.S

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

@pstanton Kodu düzelttim ve geç cevap verdiğim için üzgünüm yorum ekledim.
Karl.S

16

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 &quot;normal text&quot; and stuff using &lt;html encoding&gt;                 
    </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(/&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;
}

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

1
Bu çözümü seviyorum çünkü html özel karakterlerinin tedavisi var ... ama yine de neredeyse yeterli değil ... benim için en iyi cevap hepsiyle başa çıkacaktı. (bu muhtemelen jquery ne yapar).
Daniel Gerson

2
Bence /<p.*>/giolmalı /<p.*?>/gi.
cbron

Tüm <br>etiketleri kaldırmak için iyi bir normal ifade kullanabilirsiniz: /<br\s*\/?>/3 yerine sadece bir yerine sahip olabilirsiniz /<[a-z].*?\/?>/.
Alexis Wilke

Güzel senaryo. Peki ya tablo içeriği? Nasıl görüntülenebilir hakkında herhangi bir fikir
Hristo Enev

@DanielGerson, html kodlama gerçek kıllı, gerçek hızlı olur, ancak en iyi yaklaşım o kütüphaneyi kullanıyor gibi görünüyor
KyleMit

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

7

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

3
yikes. dizenizden bir DOM ağacı oluşturacaksanız, shog'un yolunu kullanın!
nickf

Evet, benim çözümüm, normal bir kırıcının daha uygun olduğu bir balyoz kullanmaktadır :-). Ve senin ve Shog9'un çözümlerinin daha iyi olduğunu kabul ediyorum ve temel olarak cevapta söylediler. Ben de benim html zaten bir dize içinde yer alan cevabımı yansıtmak başarısız oldu, benim cevap zaten orijinal soru açısından aslında işe yaramaz hale. :-(
Bryan

1
Adil olmak gerekirse, bunun bir değeri vardır - metnin / tamamını / tamamen korumanız gerekiyorsa, yeni satırları, sekmeleri, satır başlarını vb. ve çok daha hızlı yapın ... ha.
Shog9

7

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

4

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/


Bu düzgün bir işlevdir ve iyi belgelenmiştir. Ancak, 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ı .)
Alexis Wilke

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

İç ö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:

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


Bir öznitelik değeri içinde (örneğin string with <a malicious="attribute \">this text should be removed, but is not">example</a>) çıkış karakterleri de kullanmanız gerekir.
Logan Pickup

4

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>

3

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

11
Güvenliği önemsiyorsanız bunu yapmayın. Kullanıcı girişi şuysa: '<scr <script> ipt> alert (42); </ scr </script> ipt>' ise, çıkarılan sürüm şu olur: '<script> alert (42); </ script >'. Yani bu bir XSS güvenlik açığı.
molnarg

Geçerli bir etiket bir karakter içeremediği için [^<>]ile değiştirmelisiniz , ardından XSS güvenlik açığı ortadan kalkar. [^>]<
Alexis Wilke

3

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

3

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.


Metin kullanıcı girdisinden (textarea veya içerik düzenlenebilir widget ...) geliyorsa, bu birçok durumda başarısız olacaktır
Alexis Wilke

3

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

Web tabanlı ortamlar için mükemmel çözüm! ECMAScript 2015'ten bu yana, blok kapsamındaki değişkenler letve constiş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 .
Amin NAIRI

2

JQuery ile bunu kullanarak

$('#elementID').text()

2

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

1
Kaynağı ( phpjs) alıntılamalısınız . Eğer kullanırsanız allowedparam size XSS'e şunlardır: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')getiriler<p onclick="alert(1)">mytext</p>
Chris Cinelli

2

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.


2

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

Bu yalnızca etiketler için geçerlidir ve geniş bir işlev olması için ince ayar yapılması gerekir.
m3nda

Evet, ayrıca bir tutturucu etiketinde title="...".
Alexis Wilke


1

Kendimi çalışan düzenli bir ifade yarattım:

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

1

html şerit için basit 2 satır jquery.

 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

Kabul edilen cevap çoğunlukla iyi çalışır, ancak IE'de htmldize ('' yerine) nullalırsanız "null". Sabit:

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

1

Jquery kullanma:

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

1

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

Çalışmıyor, lütfen yanıt gönderirken her zaman kullandığınız tarayıcıdan bahsedin. Bu yanlıştır ve Chrome 61'de çalışmaz. Etiketler yalnızca bir dize olarak oluşturulur.
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);

Bunu bir jquery eklentisi olarak tanımlayın ve aşağıdaki gibi kullanın:

$.html2text(htmlContent);

Bunun kullanıcı girdisinden geldiğini varsayalım. Sayfanıza komut dosyası veya makro eklemek için kullanılabilir
Oluwatumbi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.