Strip HTML dari Teks JavaScript


655

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

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 .


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

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.


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

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.


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.


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.


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

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

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

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

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

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/


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/


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>

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

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

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.


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

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

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

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.


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

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

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

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

1

Menggunakan Jquery:

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

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

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

Katakanlah ini berasal dari input pengguna. Ini dapat digunakan untuk menambahkan skrip atau makro ke halaman Anda
Oluwatumbi
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.