Strip HTML dari Teks JavaScript

655

Apakah ada cara mudah untuk mengambil string html dalam JavaScript dan menghapus html?

Bryan
sumber

Jawaban:

761

Jika Anda menjalankan di peramban, maka cara termudah adalah membiarkan peramban melakukannya untuk Anda ...

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

Catatan: seperti yang dicatat orang di komentar, ini sebaiknya dihindari jika Anda tidak mengontrol sumber HTML (misalnya, jangan jalankan ini pada apa pun yang mungkin berasal dari input pengguna). Untuk skenario itu, Anda masih dapat membiarkan browser melakukan pekerjaan untuk Anda - lihat jawaban Saba tentang menggunakan DOMParser yang sekarang tersedia secara luas .

Shog9
sumber
40
Ingatlah bahwa pendekatan ini agak tidak konsisten dan akan gagal menghapus karakter tertentu di browser tertentu. Sebagai contoh, dalam Prototype.js, kami menggunakan pendekatan ini untuk kinerja, tetapi mengatasi beberapa kekurangan - github.com/kangax/prototype/blob/…
kangax
11
Ingat spasi putih Anda akan berantakan. Saya dulu menggunakan metode ini, dan kemudian memiliki masalah karena kode produk tertentu berisi ruang ganda, yang berakhir sebagai ruang tunggal setelah saya mendapatkan innerText kembali dari DIV. Kemudian kode produk tidak cocok nanti dalam aplikasi.
Magnus Smith
11
@Magnus Smith: Ya, jika spasi putih adalah masalah - atau benar-benar, jika Anda memiliki kebutuhan untuk teks ini yang tidak secara langsung melibatkan HTML DOM spesifik yang Anda kerjakan - maka Anda lebih baik menggunakan salah satu dari yang lain solusi yang diberikan di sini. Keuntungan utama metode ini adalah 1) sepele, dan 2) andal akan memproses tag, spasi, entitas, komentar, dll. Dengan cara yang sama seperti browser yang Anda jalankan . Itu sering berguna untuk kode klien web, tetapi tidak selalu sesuai untuk berinteraksi dengan sistem lain di mana aturannya berbeda.
Shog9
220
Jangan gunakan ini dengan HTML dari sumber yang tidak tepercaya. Untuk mengetahui alasannya, coba jalankanstrip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Mike Samuel
24
Jika html berisi gambar (tag img), gambar akan diminta oleh browser. Itu tidak baik.
douyw
591
myString.replace(/<[^>]*>?/gm, '');
nickf
sumber
4
Tidak berfungsi <img src=http://www.google.com.kh/images/srpr/nav_logo27.png onload="alert(42)" jika Anda menyuntikkan melalui document.writeatau menyatukan dengan string yang berisi >sebelum menyuntikkan melalui innerHTML.
Mike Samuel
1
@PerishableDave, saya setuju bahwa >akan dibiarkan dalam detik Tapi itu bukan bahaya injeksi. Bahaya terjadi karena <dibiarkan di yang pertama, yang menyebabkan parser HTML berada dalam konteks selain status data saat yang kedua dimulai. Perhatikan tidak ada transisi dari status data aktif >.
Mike Samuel
73
@MikeSamuel Apakah kita sudah memutuskan jawaban ini? Pengguna naif di sini siap untuk menyalin-menempel.
Ziggy
1
Ini juga, saya percaya, akan benar-benar bingung jika diberikan sesuatu seperti <button onClick="dostuff('>');"></button>Mengasumsikan HTML yang ditulis dengan benar, Anda masih perlu memperhitungkan bahwa tanda yang lebih besar dari mungkin ada di suatu tempat dalam teks yang dikutip dalam atribut. Anda juga ingin menghapus semua teks di dalam <script>tag, setidaknya.
Jonathon
15
@AntonioMax, saya sudah menjawab ini pertanyaan memuakkan , namun dengan substansi pertanyaan Anda, karena keamanan kode kritis tidak harus disalin & disisipkan. Anda harus mengunduh pustaka, dan memperbaruinya dan ditambal sehingga Anda aman terhadap kerentanan yang baru ditemukan dan untuk perubahan di browser.
Mike Samuel
249

Cara termudah:

jQuery(html).text();

Itu mengambil semua teks dari string html.

Menandai
sumber
111
Kami selalu menggunakan jQuery untuk proyek karena selalu proyek kami memiliki banyak Javascript. Karena itu kami tidak menambahkan massal, kami mengambil keuntungan dari kode API yang ada ...
Mark
32
Anda menggunakannya, tetapi OP mungkin tidak. pertanyaannya adalah tentang Javascript BUKAN JQuery.
Demensik
105
Ini masih merupakan jawaban yang berguna bagi orang-orang yang perlu melakukan hal yang sama dengan OP (seperti saya) dan tidak keberatan menggunakan jQuery (seperti saya), belum lagi, itu bisa berguna untuk OP jika mereka mempertimbangkan untuk menggunakan jQuery. Inti dari situs ini adalah untuk berbagi pengetahuan. Perlu diingat bahwa efek dingin yang mungkin Anda miliki dengan menghukum jawaban yang berguna tanpa alasan yang kuat
acjay
27
@Dementic mengejutkan, saya menemukan utas dengan beberapa jawaban menjadi yang paling berguna, karena seringkali jawaban sekunder memenuhi kebutuhan saya yang tepat, sedangkan jawaban utama memenuhi kasus umum.
Eric Goldberg
36
Itu tidak akan berfungsi jika Anda bagian string tidak dibungkus dengan tag html. mis. "<b> Kesalahan: </b> Silakan masukkan email yang valid" hanya akan mengembalikan "Kesalahan:"
Aamir Afridi
127

Saya ingin membagikan versi yang diedit dari jawaban yang disetujui Shog9 .


Seperti yang ditunjukkan Mike Samuel dengan komentar, fungsi itu dapat mengeksekusi kode javascript inline.
Tapi Shog9 benar ketika mengatakan "biarkan browser melakukannya untuk Anda ..."

jadi .. ini versi edit saya, menggunakan DOMParser :

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

di sini kode untuk menguji javascript inline:

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

Juga, itu tidak meminta sumber daya di parse (seperti gambar)

strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
Sabaz
sumber
3
Perlu ditambahkan bahwa solusi ini hanya berfungsi di browser.
kris_IV
1
Ini bukan tag strip, tetapi lebih seperti PHP htmlspecialchars (). Masih bermanfaat bagi saya.
Daantje
Perhatikan bahwa ini juga menghilangkan spasi putih dari awal teks.
Raine Revere
Juga perlu dicatat, ini bekerja di Web Pekerja
Chris Seufert
Ini sepertinya jauh lebih cepat daripada jawaban @ Shog9
Shmuel Kamensky
55

Sebagai ekstensi ke metode jQuery, jika string Anda mungkin tidak mengandung HTML (mis. Jika Anda mencoba menghapus HTML dari bidang formulir)

jQuery(html).text();`

akan mengembalikan string kosong jika tidak ada HTML

Menggunakan:

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

sebagai gantinya.

Pembaruan: Seperti yang telah ditunjukkan dalam komentar, dalam beberapa keadaan solusi ini akan mengeksekusi javascript yang terkandung di dalamnya htmljika nilai htmldapat dipengaruhi oleh penyerang, gunakan solusi yang berbeda.

pengguna999305
sumber
12
Atau$("<p>").html(html).text();
Dimitar Dimitrov
4
Ini masih mengeksekusi kode yang mungkin berbahayajQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
Simon
coba jQuery ("aa & # X003c; script> lansiran (1) & # X003c; / script> a"). text ();
Grzegorz Kaczan
41

Konversi HTML untuk Email Biasa mengirim email menjaga hyperlink (a href) tetap utuh

Fungsi di atas yang diposting oleh hypoxide berfungsi dengan baik, tetapi saya mencari sesuatu yang pada dasarnya akan mengubah HTML yang dibuat dalam editor Web RichText (misalnya FCKEditor) dan menghapus semua HTML tetapi meninggalkan semua Tautan karena fakta bahwa saya menginginkan HTML dan versi teks biasa untuk membantu membuat bagian yang benar ke email STMP (baik HTML maupun teks biasa).

Setelah lama mencari Google sendiri dan kolega saya datang dengan menggunakan mesin regex di Javascript:

str='this string has <i>html</i> code i want to <b>remove</b><br>Link Number 1 -><a href="http://www.bbc.co.uk">BBC</a> Link Number 1<br><p>Now back to normal text and stuff</p>
';
str=str.replace(/<br>/gi, "\n");
str=str.replace(/<p.*>/gi, "\n");
str=str.replace(/<a.*href="(.*?)".*>(.*?)<\/a>/gi, " $2 (Link->$1) ");
str=str.replace(/<(?:.|\s)*?>/g, "");

yang strvariabel dimulai seperti ini:

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>

dan kemudian setelah kode itu dijalankan terlihat seperti ini: -

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

Seperti yang Anda lihat, semua HTML telah dihapus dan Tautan telah dipertahankan dengan teks hyperlink masih utuh. Saya juga telah mengganti tag <p>dan <br>dengan \n(baris baru char) sehingga semacam pemformatan visual telah dipertahankan.

Untuk mengubah format tautan (mis. BBC (Link->http://www.bbc.co.uk)) Cukup edit $2 (Link->$1), di mana $1href URL / URI dan $2teksnya adalah hyperlink. Dengan tautan langsung di badan teks biasa, sebagian besar Klien Mail SMTP mengonversi ini sehingga pengguna memiliki kemampuan untuk mengekliknya.

Semoga Anda menemukan ini berguna.

Jibberboy2000
sumber
Itu tidak menangani "& nbsp;"
Rose Nettoyeur
33

Peningkatan jawaban yang diterima.

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

Dengan cara ini sesuatu yang berjalan seperti ini tidak akan membahayakan:

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

Firefox, Chromium, dan Explorer 9+ aman. Opera Presto masih rentan. Juga gambar yang disebutkan dalam string tidak diunduh di Chromium dan Firefox yang menyimpan permintaan http.

Janghou
sumber
Ini adalah beberapa cara di sana, tetapi tidak aman dari<script><script>alert();
Arth
1
Itu tidak menjalankan skrip apa pun di sini di Chromium / Opera / Firefox di Linux, jadi mengapa tidak aman?
Janghou
Maaf, saya pasti salah tes, saya mungkin lupa klik run lagi di jsFiddle.
Arth
Argumen "Baru" itu berlebihan, saya pikir?
Jon Schneider
Menurut spesifikasi itu opsional saat ini, tetapi tidak selalu.
Janghou
23

Ini harus dilakukan pada lingkungan Javascript apa pun (termasuk 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, '');
Karl.S
sumber
@pstanton, bisakah Anda memberikan contoh pernyataan Anda yang berfungsi?
Karl.S
3
<html><style..>* {font-family:comic-sans;}</style>Some Text</html>
pstanton
@pstanton Saya telah memperbaiki kode dan menambahkan komentar, maaf atas tanggapan yang terlambat.
Karl.
16

Saya mengubah jawaban Jibberboy2000 untuk menyertakan beberapa <BR />format tag, menghapus semua yang ada di dalam <SCRIPT>dan <STYLE>tag, memformat HTML yang dihasilkan dengan menghapus beberapa jeda baris dan spasi, dan mengonversi beberapa kode yang dikodekan HTML menjadi normal. Setelah beberapa pengujian tampak bahwa Anda dapat mengubah sebagian besar halaman web penuh menjadi teks sederhana di mana judul halaman dan konten dipertahankan.

Dalam contoh sederhana,

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

menjadi

Ini judul saya

String ini memiliki kode html yang ingin saya hapus

Di baris ini BBC ( http://www.bbc.co.uk ) dengan tautan disebutkan.

Sekarang kembali ke "teks normal" dan menggunakan hal-hal

Fungsi JavaScript dan halaman pengujian terlihat seperti ini:

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

Itu digunakan dengan HTML ini:

<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 />
Elendurwen
sumber
1
Saya suka solusi ini karena memiliki perawatan karakter html khusus ... tetapi masih belum cukup dari mereka ... jawaban terbaik bagi saya akan berurusan dengan mereka semua. (yang mungkin apa yang dilakukan jquery).
Daniel Gerson
2
Saya pikir /<p.*>/giseharusnya begitu /<p.*?>/gi.
cbron
Perhatikan bahwa untuk menghapus semua <br>tag Anda bisa menggunakan ekspresi reguler baik bukan: /<br\s*\/?>/cara itu Anda hanya memiliki satu menggantikan bukannya 3. Juga tampaknya bagi saya bahwa kecuali untuk decoding entitas Anda dapat memiliki satu regex, sesuatu seperti ini: /<[a-z].*?\/?>/.
Alexis Wilke
Naskah yang bagus. Tapi bagaimana dengan konten tabel? Setiap ide bagaimana bisa ditampilkan
Hristo Enev
@DanielGerson, enkode html menjadi sangat berbulu, sangat cepat, tetapi pendekatan terbaik tampaknya menggunakan perpustakaan he
KyleMit
15
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");

Ini adalah versi regex, yang lebih tangguh terhadap HTML yang rusak, seperti:

Tag tidak tertutup

Some text <img

"<", ">" atribut tag di dalam

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

Baris baru

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

Kode

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

Solusi lain, yang diakui kurang elegan daripada nickf atau Shog9, adalah berjalan secara DOM mulai dari tag <body> dan menambahkan setiap node teks.

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;
}
Bryan
sumber
3
Astaga. jika Anda akan membuat pohon DOM dari string Anda, maka cukup gunakan cara shog!
nickf
Ya, solusi saya menggunakan palu godam di mana palu biasa lebih tepat :-). Dan saya setuju bahwa solusi Anda dan Shog9 lebih baik, dan pada dasarnya mengatakan sebanyak mungkin dalam jawabannya. Saya juga gagal merefleksikan dalam tanggapan saya bahwa html sudah terkandung dalam sebuah string, menjadikan jawaban saya pada dasarnya tidak berguna sehubungan dengan pertanyaan asli. :-(
Bryan
1
Agar adil, ini memiliki nilai - jika Anda benar-benar harus mempertahankan / semua / dari teks, maka ini setidaknya memiliki kesempatan yang baik dalam menangkap baris baru, tab, carriage return, dll ... Kemudian lagi, solusi nick harus melakukan hal yang sama , dan lakukan lebih cepat ... eh.
Shog9
7

Jika Anda ingin menyimpan tautan dan struktur konten (h1, h2, dll) maka Anda harus memeriksa TextVersionJS Anda dapat menggunakannya dengan HTML apa pun, meskipun itu dibuat untuk mengubah email HTML menjadi teks biasa.

Penggunaannya sangat sederhana. Misalnya di node.js:

var createTextVersion = require("textversionjs");
var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";

var textVersion = createTextVersion(yourHtml);

Atau di browser dengan js murni:

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

Ini juga bekerja dengan require.js:

define(["textversionjs"], function(createTextVersion) {
  var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
  var textVersion = createTextVersion(yourHtml);
});
gyula. nemeth
sumber
4

Setelah mencoba semua jawaban yang disebutkan sebagian besar jika tidak semuanya memiliki kasus tepi dan tidak dapat sepenuhnya mendukung kebutuhan saya.

Saya mulai mengeksplorasi bagaimana php melakukannya dan menemukan lib php.js yang mereplikasi metode strip_tags di sini: http://phpjs.org/functions/strip_tags/

Deminetix
sumber
Ini adalah fungsi yang rapi dan didokumentasikan dengan baik. Namun, itu dapat dibuat lebih cepat ketika allowed == ''yang saya pikir adalah apa yang diminta OP, yang hampir seperti yang dijawab Byron di bawah ini (Byron hanya [^>]salah.)
Alexis Wilke
1
Jika Anda menggunakan allowedparam, Anda rentan terhadap XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')pengembalian<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('');
}

Akun untuk atribut dalam dan <img onerror="javascript">dalam elemen dom yang baru dibuat.

pemakaian:

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

demo:

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

demo jawaban teratas melakukan hal-hal buruk:

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

pengguna40521
sumber
Anda harus menangani tanda kutip yang lolos di dalam nilai atribut juga (mis string with <a malicious="attribute \">this text should be removed, but is not">example</a>.).
Logan Pickup
4

Banyak orang sudah menjawab ini, tapi saya pikir mungkin berguna untuk membagikan fungsi yang saya tulis yang menghapus tag HTML dari sebuah string tetapi memungkinkan Anda untuk memasukkan array tag yang tidak ingin Anda hapus. Cukup singkat dan telah bekerja dengan baik untuk saya.

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>
Harry Stevens
sumber
3

Saya pikir cara termudah adalah dengan hanya menggunakan Ekspresi Reguler seperti seseorang yang disebutkan di atas. Meskipun tidak ada alasan untuk menggunakan banyak dari mereka. Mencoba:

stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
Byron Carasco
sumber
11
Jangan lakukan ini jika Anda peduli dengan keamanan. Jika input pengguna adalah ini: '<scr <script> ipt> alert (42); </ scr </script> ipt>' maka versi yang dilucuti adalah ini: '<script> alert (42); </ script > '. Jadi ini adalah kerentanan XSS.
molnarg
Anda harus mengubah [^<>]dengan [^>]karena tag yang valid tidak dapat menyertakan <karakter, maka kerentanan XSS menghilang.
Alexis Wilke
3

Saya membuat beberapa modifikasi pada skrip Jibberboy2000 asli Semoga bermanfaat bagi seseorang

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");
Jaxolotl
sumber
3

Berikut adalah versi yang agaknya membahas masalah keamanan @ MikeSamuel:

function strip(html)
{
   try {
       var doc = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null);
       doc.documentElement.innerHTML = html;
       return doc.documentElement.textContent||doc.documentElement.innerText;
   } catch(e) {
       return "";
   }
}

Catatan, itu akan mengembalikan string kosong jika markup HTML tidak sah XML (alias, tag harus ditutup dan atribut harus dikutip). Ini tidak ideal, tetapi menghindari masalah memiliki potensi mengeksploitasi keamanan.

Jika tidak memiliki markup XML yang valid adalah persyaratan untuk Anda, Anda dapat mencoba menggunakan:

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

tapi itu juga bukan solusi yang sempurna karena alasan lain.

Jeremy Johnstone
sumber
Itu akan gagal dalam banyak keadaan jika teks tersebut berasal dari input pengguna (textarea atau widget yang dapat diedit ...)
Alexis Wilke
3

Anda dapat dengan aman menghapus tag html menggunakan atribut sandbox iframe .

Idenya di sini adalah bahwa alih-alih mencoba regex string kami, kami mengambil keuntungan dari parser asli browser dengan menyuntikkan teks ke dalam elemen DOM dan kemudian meminta textContent/ innerTextproperti dari elemen itu.

Elemen yang paling cocok untuk menyuntikkan teks kita adalah iframe kotak pasir, dengan cara itu kita dapat mencegah eksekusi kode arbitrer (Juga dikenal sebagai XSS ).

Kelemahan dari pendekatan ini adalah ia hanya berfungsi di browser.

Inilah yang saya buat (Tidak teruji perang):

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

Penggunaan ( 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));
Etienne Martin
sumber
Solusi hebat untuk lingkungan berbasis web! Anda mungkin tidak boleh menggunakan IIFE karena sejak ECMAScript 2015, variabel blok-dicakup sudah dicakup ke blok dengan benar dengan letdan constoperator. Juga, menggunakan solusi Anda, saya mendapat banyak referensi untuk iframestidak digunakan di dalam dokumen. Pertimbangkan untuk menambahkan document.body.removeChild(sandbox)kode untuk pembaca berbasis pasta yang akan datang.
Amin NAIRI
2

Dengan jQuery, Anda cukup mengambilnya dengan menggunakan

$('#elementID').text()
ianaz
sumber
2

Kode di bawah ini memungkinkan Anda untuk mempertahankan beberapa tag html sambil menghapus semua yang lain

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 : '';
      });
}
aWebDeveloper
sumber
1
Anda harus mengutip sumbernya ( phpjs). Jika Anda menggunakan allowedparam, Anda rentan terhadap XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')pengembalian<p onclick="alert(1)">mytext</p>
Chris Cinelli
2

Dimungkinkan juga untuk menggunakan parser JS HTML htmlparser2 murni yang fantastis . Ini demo yang berfungsi:

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

Outputnya adalah This is a simple example.

Lihat beraksi di sini: https://tonicdev.com/jfahrenkrug/extract-text-from-html

Ini berfungsi di kedua simpul dan browser jika Anda mengemas aplikasi web Anda menggunakan alat seperti webpack.

Johannes Fahrenkrug
sumber
2

Saya hanya perlu menghapus <a>tag dan menggantinya dengan teks tautan.

Ini sepertinya bekerja dengan baik.

htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');
Friggin Yang Mulia
sumber
Ini hanya berlaku untuk tag dan perlu penyesuaian untuk menjadi fungsi yang luas.
m3nda
Ya, ditambah tag jangkar dapat memiliki banyak atribut lain seperti title="...".
Alexis Wilke
1

Saya sendiri telah membuat ekspresi reguler:

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

jquery 2 baris sederhana untuk menghapus html.

 var content = "<p>checking the html source&nbsp;</p><p>&nbsp;
  </p><p>with&nbsp;</p><p>all</p><p>the html&nbsp;</p><p>content</p>";

 var text = $(content).text();//It gets you the plain text
 console.log(text);//check the data in your console

 cj("#text_area_id").val(text);//set your content to text area using text_area_id
Pengembang
sumber
1

Jawaban yang diterima sebagian besar berfungsi dengan baik, namun di IE jika htmlstring nullAnda mendapatkan "null"(bukan ''). Tetap:

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

Menggunakan Jquery:

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

inputelemen hanya mendukung satu teks baris :

Status teks mewakili kontrol edit teks biasa satu baris untuk nilai elemen.

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

Pembaruan: ini berfungsi seperti yang diharapkan

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;
}
Mike Datsko
sumber
Tidak berfungsi, harap selalu sebutkan browser yang Anda gunakan saat memposting jawaban. Ini tidak akurat dan tidak akan berfungsi di Chrome 61. Tag hanya diberikan sebagai string.
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);

Tetapkan ini sebagai plugin jquery dan gunakan seperti berikut:

$.html2text(htmlContent);
Shiv Shankar
sumber
Katakanlah ini berasal dari input pengguna. Ini dapat digunakan untuk menambahkan skrip atau makro ke halaman Anda
Oluwatumbi