jQuery(几乎)相当于PHP的strip_tags()函数

37

有没有jQuery版本的这个函数?

string strip_tags( string $str [, string $allowable_tags ] )

从字符串中删除所有标签及其内部内容,但保留允许使用的标签。

例如:

var stripped = strip_tags($('#text').html(), '<p><em><i><b><strong><code>');

来自:

<div id="text">
  <p> paragraph </p>
  <div> should be stripped </div>
</div>

7
phpjs.org 提供了该函数的一个移植版本。 - lonesomeday
strip_tags函数[不会]删除被剥离标签的内容(http://php.net/manual/en/function.strip-tags.php)。 - Lightness Races in Orbit
当一个标签被剥离时,您是否希望其子元素也被删除?您能否澄清一下? - karim79
实际上我改变了主意 :) 在我的情况下只剥离标签更好。来自phpjs.org的函数非常棒! - Alex
请注意,不要使用正则表达式,因为会发生糟糕的事情 - styfle
显示剩余2条评论
9个回答

36

要删除标签,但不删除内容,就像 PHP 中的strip_tags()函数一样,可以这样做:

var whitelist = "p"; // for more tags use the multiple selector, e.g. "p, img"
$("#text *").not(whitelist).each(function() {
    var content = $(this).contents();
    $(this).replaceWith(content);
});

在这里试一试。


我已经尝试过 $("*").each()...,看起来似乎工作正常,除非我漏掉了什么。 - gargantuan
如何在文本区域中使其工作?例如,如果我按下一个按钮,则文本区域内的所有HTML标记都应该被删除。 - Black
<script> 标签怎么办?它们没有被列入白名单,但仍然存在于输出中。 - styfle
非常好的一个。谢谢! - VGranin

30
为了删除所有标记,您可以使用:

strip_tags()

$('<div>Content</div>').text()

$('dsfsadfasdfasdfasdf<a>sdfsdf</a>').text()会返回"sdfsdf",因此丢失了文本的前半部分。 - aabele
1
是的,只有在文本被包裹在某个HTML标签内部时才会起作用。 - timfjord
9
所以使用 $('<p>'+content+'</p>').text(); 代码。 - commonpike
.text() is more equivalent to PHP htmlspecialchars() than strip_tags(). Example: outside html - <strong>inside html</strong> strip_tags will be outside html - inside html but .text() will be outside html - <strong>inside html</strong> where < is &lt; and > is &gt; - vee
2
XSS警告:此方法还会解码实体,例如Foo &lt;script&gt;alert('XSS')&lt;/script&gt; <span>Bar</span>将变为Foo <script>alert('XSS')</script> Bar。PHP的strip_tags不会这样做。 - Lionel

14

只需使用正则表达式:

html.replace( /<.*?>/g, '' );
完成。 :)
对于 p 标签:
html.replace( /<[^p].*?>/g, '' );

对于其他标签,情况会变得更加复杂。


1
换行符打断了这个正则表达式:'<tag\n>'.replace(/<.*?>/g,'') // <tag\n>要解决这个问题,使用 [\s\S] 替换点号:/<[\s\S]*?>/g - oriadam
1
...或者 /<[^>]*>/g - oriadam

11

这对我有用:

function strip_tags(str) {
    str = str.toString();
    return str.replace(/<\/?[^>]+>/gi, '');
}

1
我投票支持这个答案,因为它是唯一一个能够在没有副作用的情况下完成工作的答案。如果可以的话,我会减半分,因为这个函数不允许标签白名单(而我并不需要)。 - Daniel

7
即使这是一个旧的线程,我认为它仍然对那些仍在寻找答案的人有用。 Locutus.io函数似乎是最好的解决方案。
function strip_tags (input, allowed) {
      allowed = (((allowed || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('')
      var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi
      var commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi
      return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
        return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''
      })
}

例子 1:

strip_tags('<p>Kevin</p> <br /><b>van</b> <i>Zonneveld</i>', '<i><b>')

返回值 1:'Kevin <b>van</b> <i>Zonneveld</i>'

示例 2:

strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>')

返回值 2:'<p>Kevin van Zonneveld</p>'

示例 3:

strip_tags("<a href='http://kvz.io'>Kevin van Zonneveld</a>", "<a>")

返回 3:"<a href='http://kvz.io'>Kevin van Zonneveld</a>"

示例 4:

strip_tags('1 < 5 5 > 1')

返回结果为4:'1 < 5 5 > 1'

示例5:

strip_tags('1 <br/> 1')

返回5: '1 1'

示例6:

strip_tags('1 <br/> 1', '<br>')

返回6: '1 <br/> 1'

例子7:

strip_tags('1 <br/> 1', '<br><br/>')

returns 7: '1 <br/> 1'


4

虽然不是一个实际的答案,但需要注意(取决于您想要做什么):

在我看来,在几乎所有情况下,输入验证应该在服务器端完成(在这种情况下,使用本机PHP函数)。如果您的意图是用客户端功能替换PHP功能,我强烈建议不要这样做。

为什么?

只因为您正在编写网站,并不意味着:

  1. 您的用户启用了JavaScript。如果您不通过脚本严格提交表单(使用提交按钮等),它仍然允许用户提交无效数据(如<script>标记等)
  2. 请求可能根本不是由浏览器发起的,从而绕过任何基于JS的输入验证。

再次强调,这并不是真正回答您的问题,而是基于您可能会面临的问题提出的建议。


不,我正在尝试允许访问者在评论时“引用”评论。当他们点击引用按钮时,我希望被引用的评论文本出现在文本区域中,没有标签,因为这可能会吓到他们。 - Alex
@Alex - 看看我回答中链接的示例。我故意给p标签上色以强调“白名单”保持不变。所有文本都被保留。 - karim79
@Alex - 我想你是想接受karim79的答案,而不是我的 :) - Demian Brecht
因为“答案”不是一个答案,而且假设OP无知,不知道他们需要什么,所以被踩了。最好在反对基于假定用例的说教之前理解为什么有人会问这样的问题。 - MikeSchinkel
@mikeschinkel:这并不是每天都会在两年之后被踩的事情 :) - Demian Brecht

4
为了去掉所有标签,可以使用以下方法:
var StrippedString = OriginalString.replace(/(<([^>]+)>)/ig,"");

代码来源:JavaScript中的去除HTML标签


“str.replace(/<[^>]+>/ig, "")”会产生相同的效果,不需要括号。 - oriadam

2

1

更新

使用以下内容去除标签同时保留内容

$('#text').find('p').contents().unwrap();

这将删除 '#text' 的子元素 p 标签。

请查看工作示例 http://jsfiddle.net/YWCsH/


这不是 strip_tags 的作用。OP说从剥离标签内部的内容被删除,但这并不是真的 - Lightness Races in Orbit
@Hussein:实际上,无论是他的文字还是他的示例都没有明确说明(他只是错误地描述了strip_tags的功能)。我们唯一能确定的事情是,他想要一个与你的JavaScript不同行为的strip_tags的端口。 - Lightness Races in Orbit
她是女性。无论她是否正确引用了 strip_tags,这是我从她的问题中理解到的。 - Hussein
@Hussein:好的,无论如何都是一场赌博:让我们等着瞧。 :) - Lightness Races in Orbit
@Alex:抱歉,我没有检查你的性别。反射打字 :) - Lightness Races in Orbit
XSS警告,像这样的安全字符串&lt;script&gt;evil()&lt;script&gt;将会被这种方法转换为一个恶意脚本。 - oriadam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接