有没有一种简单的方法可以在 JavaScript 中获取一串 html 并去除 html?
如果您在浏览器中运行,那么最简单的方法就是let the browser do it for you...
function stripHtml(html)
{
let tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
注意:正如人们在评论中指出的那样,如果您不控制 HTML 的源,最好避免这种情况(例如,不要在任何可能来自用户输入的内容上运行它)。对于这些情况,您仍然可以让浏览器为您完成工作 - see Saba's answer on using the now widely-available DOMParser。
myString.replace(/<[^>]*>?/gm, '');
document.write
注入或在通过 innerHTML
注入之前与包含 >
的字符串连接,则不适用于 <img src=http://www.google.com.kh/images/srpr/nav_logo27.png onload="alert(42)"
。
>
将留在第二个。不过,这不是注射危险。由于 <
留在第一个中,从而导致 HTML 解析器在第二个启动时处于 data state 以外的上下文中,因此发生危险。请注意,>
上的数据状态没有转换。
<button onClick="dostuff('>');"></button>
之类的内容,这也会完全混淆。假设 HTML 编写正确,您仍然需要考虑到属性中引用的文本中可能存在大于号。此外,您至少希望删除 <script>
标记内的所有文本。
最简单的方法:
jQuery(html).text();
从一串html中检索所有文本。
我想分享 Shog9's approved answer 的编辑版本。
正如 Mike Samuel 在评论中指出的那样,该函数可以执行内联 javascript 代码。但是 Shog9 说“让浏览器为你做这件事……”是对的。
所以..这里是我编辑的版本,使用 DOMParser:
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(例如,如果您尝试从表单字段中删除 HTML)
jQuery(html).text();
如果没有 HTML,将返回一个空字符串
利用:
jQuery('<p>' + html + '</p>').text();
反而。
更新: 正如评论中所指出的,在某些情况下,如果 html
的值可能受到攻击者的影响,此解决方案将执行 html
中包含的 javascript,请使用不同的解决方案。
$("<p>").html(html).text();
jQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
将 HTML 转换为纯文本电子邮件,保持超链接 (a href) 不变
hypoxide 发布的上述函数工作正常,但我想要的东西基本上可以转换在 Web RichText 编辑器(例如 FCKEditor)中创建的 HTML 并清除所有 HTML 但保留所有链接,因为我想要 HTML 和纯文本版本,以帮助为 STMP 电子邮件(HTML 和纯文本)创建正确的部分。
在我自己和我的同事在 Javascript 中使用正则表达式引擎搜索 Google 很长时间之后,我想出了这个:
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();
来说并不安全
这应该可以在任何 Javascript 环境(包括 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>
我更改了 Jibberboy2000's answer 以包含几种 <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
。
<br>
标记,您可以改用一个好的正则表达式:/<br\s*\/?>/
这样您只有一个替换而不是 3 个。在我看来,除了实体的解码之外,您可以有一个正则表达式,类似这样:/<[a-z].*?\/?>/
。
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");
这是一个正则表达式版本,它对格式错误的 HTML 更具弹性,例如:
未封闭的标签
Some text <img
标签属性内的“<”、“>”
Some text <img alt="x > y">
换行符
Some <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 标记及其属性不变。
const deTagged = myString.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, ''); const deNewlined = deTagged.replace(/\n/g, '');
来自 CSS 技巧:
https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/
const originalString = `
嘿,那是 somthing
[^<>]
更改为 [^>]
,因为有效标签不能包含 <
字符,然后 XSS 漏洞就会消失。
下面的代码允许您保留一些 html 标签,同时剥离所有其他标签
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
)。如果您使用 allowed
参数,您很容易受到 XSS 攻击:stripTags('<p onclick="alert(1)">mytext</p>', '<p>')
返回 <p onclick="alert(1)">mytext</p>
我只需要去掉 <a>
标记并将它们替换为链接的文本。
这似乎工作得很好。
htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');
title="..."
。
接受的答案大部分都可以正常工作,但是在 IE 中,如果 html
字符串是 null
,您会得到 "null"
(而不是 '')。固定的:
function strip(html)
{
if (html == null) return "";
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
使用 jQuery 剥离 html 的一种更安全的方法是首先使用 jQuery.parseHTML 创建一个 DOM,忽略任何脚本,然后让 jQuery 构建一个元素,然后只检索文本。
function stripHtml(unsafe) {
return $($.parseHTML(unsafe)).text();
}
可以安全地从以下位置剥离 html:
<img src="unknown.gif" onerror="console.log('running injections');">
和其他漏洞。
开心!
使用 jQuery,您可以简单地使用
$('#elementID').text()
我自己创建了一个工作正则表达式:
str=str.replace(/(<\?[a-z]*(\s[^>]*)?\?(>|$)|<!\[[a-z]*\[|\]\]>|<!DOCTYPE[^>]*?(>|$)|<!--[\s\S]*?(-->|$)|<[a-z?!\/]([a-z0-9_:.])*(\s[^>]*)?(>|$))/gi, '');
简单的 2 行 jquery 来剥离 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
使用jQuery:
function stripTags() {
return $('<p></p>').html(textToEscape).text()
}
input
元素 support only one line text:
文本状态表示元素值的单行纯文本编辑控件。
function stripHtml(str) {
var tmp = document.createElement('input');
tmp.value = str;
return tmp.value;
}
更新:这按预期工作
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;
}
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")