如果你在浏览器中运行,那么最简单的方法就是让浏览器为你完成...
function stripHtml(html)
{
let tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
注意:正如评论中的人们所指出的,如果您不控制HTML的源代码(例如,不要在任何可能来自用户输入的内容上运行此代码),最好避免使用此方法。对于这些情况,您仍然可以让浏览器为您完成工作-请参见Saba的答案,使用现在广泛可用的DOMParser。
myString.replace(/<[^>]*>?/gm, '');
document.write
注入或通过包含>
的字符串进行串联后再通过innerHTML
注入,则无法针对<img src=http://www.google.com.kh/images/srpr/nav_logo27.png onload="alert(42)"
执行。 - Mike Samuel>
会被保留。但这并不是注入风险。风险出现在第一个<
被保留的情况下,这会导致HTML解析器在第二个开始时处于除data state之外的上下文中。请注意,没有从数据状态转换到>
。 - Mike Samuel<button onClick="dostuff('>');"></button>
这样的代码,我相信它会产生混淆。即使是正确编写的HTML,您仍然需要考虑引号内可能包含大于号的情况。另外,您可能希望至少删除所有<script>
标签内的文本。 - Jonathon我想分享编辑过的Shog9批准的答案。
正如Mike Samuel在评论中指出的那样,该函数可以执行内联JavaScript代码。
但是Shog9说得对,“让浏览器为你完成...”
因此,这是我的编辑版本,使用DOM解析器:
function strip(html){
let doc = new DOMParser().parseFromString(html, 'text/html');
return doc.body.textContent || "";
}
这里是测试内联JavaScript代码的代码:
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
另外,它在解析过程中不会请求资源(如图像)
strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
最简单的方法:
jQuery(html).text();
这会从一个 HTML 字符串中获取所有的文本。
作为jQuery方法的一个扩展,如果你的字符串可能不包含HTML(例如,如果你想从表单字段中删除HTML),
jQuery(html).text();
如果没有HTML,将返回空字符串
使用:
jQuery('<p>' + html + '</p>').text();
更新: 根据评论所指出的,在某些情况下,如果html
的值可能受到攻击者的影响,则此解决方案将执行包含在html
内的javascript,请使用其他解决方案。 而不是。
$("<p>").html(html).text();
的意思是将一个包含 HTML 标签的字符串转换为纯文本格式的字符串。 - Dimitar DimitrovjQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
。 - Simonhypoxide发布的上述函数效果很好,但我想要的是能够将在Web富文本编辑器(例如FCKEditor)中创建的HTML转换成纯文本,并清除所有HTML标记,但保留所有链接的内容。这是因为我希望同时拥有HTML和纯文本版本以便于创建STMP电子邮件的正确部分(包含HTML和纯文本)。
在经过长时间的谷歌搜索后,我和我的同事使用了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, "");
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>
然后在代码运行后,它看起来像这样:
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
可以看到,所有的HTML标记都被删除了,链接已经保留,超链接文本仍然完整。我还用换行符\n
(换行字符)替换了<p>
和<br>
标签,以便保留一定的视觉格式。
要更改链接格式(例如BBC(Link->http://www.bbc.co.uk)
),只需编辑$2(Link->$1)
,其中$1
是href URL / URI,而$2
是超链接文本。对于纯文本正文中直接使用链接,大多数SMTP邮件客户端会将其转换为用户可以单击的链接。
希望您觉得这个有用。
对被接受答案的改进。
function strip(html)
{
var tmp = document.implementation.createHTMLDocument("New").body;
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
这样运行起来就不会有任何问题:
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Firefox、Chromium和Explorer 9+是安全的。 Opera Presto仍然存在漏洞。 此外,在Chromium和Firefox中,提到的图片不会被下载,这有助于节省HTTP请求。
<script><script>alert();
的安全问题。 - Arth 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>/g, '')
// Remove script tags and content
.replace(/<script[^>]*>.*<\/script>/g, '')
// Remove all opening, closing and orphan HTML tags
.replace(/<[^>]+>/g, '')
// Remove leading spaces and repeated CR/LF
.replace(/([\r\n]+ +)+/g, '');
<html><style..>* {font-family:comic-sans;}</style>Some Text</html>
可以翻译为: <html><style..>* {字体族谱:漫画 sans;}</style>一些文本</html>
。 - pstantonm
模式修饰符是无意义的。由于前两个模式具有共同的开始和结束,因此可以通过捕获标记名称,然后使用反向引用来 consolide 它们的内容。 - mickmackusavar text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
这是一个正则表达式版本,可以更好地处理格式不正确的HTML,例如:
未关闭的标签
一些文本 <img
标签属性中的 "<", ">"
一些文本 <img alt="x > y">
换行符
一些 <a
href="http://google.com">
代码
var html = '<br>This <img alt="a>b" \r\n src="a_b.gif" />is > \nmy<>< > <a>"text"</a'
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
string.replace()
,并保留任何HTML标签及其属性不变。 - Ade`const deTagged = myString.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, '');
const deNewlined = deTagged.replace(/\n/g, '');`
- Leigh Mathieson我修改了Jibberboy2000的答案,增加了几种<BR />
标记格式,删除了所有<SCRIPT>
和<STYLE>
标签内的内容,通过删除多余的换行符和空格并将一些HTML编码转换为普通文本来格式化生成的HTML。经过测试,似乎可以将大部分完整的网页转换为只保留页面标题和内容的简单文本。
在这个简单的例子中,
<!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>
变成
这是我的标题
这个字符串包含我想要删除的html代码
这一行提到了带有链接的BBC (http://www.bbc.co.uk)。
现在回到“正常文本”和使用的东西
JavaScript函数和测试页面如下所示:
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;
}
它与以下HTML一起使用:
<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
应该是 /<p.*?>/gi
。 - cbron<br>
标签,您可以使用一个好的正则表达式而不是三个替换,例如:/<br\s*\/?>/
。此外,除了解码实体之外,您似乎可以使用一个单独的正则表达式,类似于:/<[a-z].*?\/?>/
。 - Alexis Wilke
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
。 - Mike Samuel