Jawaban:
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 .
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)"
jika Anda menyuntikkan melalui document.write
atau menyatukan dengan string yang berisi >
sebelum menyuntikkan melalui innerHTML
.
>
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 >
.
<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.
Cara termudah:
jQuery(html).text();
Itu mengambil semua teks dari string html.
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'>")
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 html
jika nilai html
dapat dipengaruhi oleh penyerang, gunakan solusi yang berbeda.
$("<p>").html(html).text();
jQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
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 str
variabel 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 $1
href URL / URI dan $2
teksnya 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.
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.
<script><script>alert();
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, '');
<html><style..>* {font-family:comic-sans;}</style>Some Text</html>
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 "normal text" and stuff using <html encoding>
</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(/ /gi," ");
returnText=returnText.replace(/&/gi,"&");
returnText=returnText.replace(/"/gi,'"');
returnText=returnText.replace(/</gi,'<');
returnText=returnText.replace(/>/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 />
/<p.*>/gi
seharusnya begitu /<p.*?>/gi
.
<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].*?\/?>/
.
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, "");
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;
}
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);
});
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/
allowed == ''
yang saya pikir adalah apa yang diminta OP, yang hampir seperti yang dijawab Byron di bawah ini (Byron hanya [^>]
salah.)
allowed
param, Anda rentan terhadap XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')
pengembalian<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('');
}
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:
string with <a malicious="attribute \">this text should be removed, but is not">example</a>
.).
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>
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, "");
[^<>]
dengan [^>]
karena tag yang valid tidak dapat menyertakan <
karakter, maka kerentanan XSS menghilang.
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");
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.
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
/ innerText
properti 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));
let
dan const
operator. Juga, menggunakan solusi Anda, saya mendapat banyak referensi untuk iframes
tidak digunakan di dalam dokumen. Pertimbangkan untuk menambahkan document.body.removeChild(sandbox)
kode untuk pembaca berbasis pasta yang akan datang.
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 : '';
});
}
phpjs
). Jika Anda menggunakan allowed
param, Anda rentan terhadap XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')
pengembalian<p onclick="alert(1)">mytext</p>
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.
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, '');
title="..."
.
Untuk solusi yang lebih mudah, coba ini => https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/
var StrippedString = OriginalString.replace(/(<([^>]+)>)/ig,"");
jquery 2 baris sederhana untuk menghapus html.
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
Jawaban yang diterima sebagian besar berfungsi dengan baik, namun di IE jika html
string null
Anda mendapatkan "null"
(bukan ''). Tetap:
function strip(html)
{
if (html == null) return "";
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
input
elemen 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;
}
(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);