strip_tags
文档,第二个参数指定允许的标签。然而在我的情况下,我想要相反的效果。也就是说,我会接受script_tags
通常(默认)接受的标签,但只去掉<script>
标签。是否有可能实现这一点?任何相关的建议将不胜感激。strip_tags
文档,第二个参数指定允许的标签。然而在我的情况下,我想要相反的效果。也就是说,我会接受script_tags
通常(默认)接受的标签,但只去掉<script>
标签。是否有可能实现这一点?任何相关的建议将不胜感激。编辑
要使用HTML Purifier的HTML.ForbiddenElements
配置指令,似乎您需要执行以下操作:
require_once '/path/to/HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.ForbiddenElements', array('script','style','applet'));
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($dirty_html);
HTML.ForbiddenElements
应该设置为一个数组
。我不知道数组
成员应该采取什么形式:
array('script','style','applet')
或者:
array('<script>','<style>','<applet>')
还是......其他什么?
我认为它是第一种形式,没有分隔符;HTML.AllowedElements
使用了一种配置字符串形式,这种形式在TinyMCE的valid elements
语法中相当常见:
tinyMCE.init({
...
valid_elements : "a[href|target=_blank],strong/b,div[align],br",
...
});
HTML.ForbiddenAttributes
)。但这只是一个猜测。HTML.ForbiddenAttributes
文档的这个注释:%HTML.ForbiddenElements
,因此请查看该指令以讨论为什么在使用此指令之前应三思而后行。:)
HTML.ForbiddenElements
配置指令,但如果你真的非常想使用strip_tags()
,那么从黑名单中派生出一个白名单是一个合理的选择。换句话说,删除你不想要的内容,然后使用剩下的内容。
例如:
function blacklistElements($blacklisted = '', &$errors = array()) {
if ((string)$blacklisted == '') {
$errors[] = 'Empty string.';
return array();
}
$html5 = array(
"<menu>","<command>","<summary>","<details>","<meter>","<progress>",
"<output>","<keygen>","<textarea>","<option>","<optgroup>","<datalist>",
"<select>","<button>","<input>","<label>","<legend>","<fieldset>","<form>",
"<th>","<td>","<tr>","<tfoot>","<thead>","<tbody>","<col>","<colgroup>",
"<caption>","<table>","<math>","<svg>","<area>","<map>","<canvas>","<track>",
"<source>","<audio>","<video>","<param>","<object>","<embed>","<iframe>",
"<img>","<del>","<ins>","<wbr>","<br>","<span>","<bdo>","<bdi>","<rp>","<rt>",
"<ruby>","<mark>","<u>","<b>","<i>","<sup>","<sub>","<kbd>","<samp>","<var>",
"<code>","<time>","<data>","<abbr>","<dfn>","<q>","<cite>","<s>","<small>",
"<strong>","<em>","<a>","<div>","<figcaption>","<figure>","<dd>","<dt>",
"<dl>","<li>","<ul>","<ol>","<blockquote>","<pre>","<hr>","<p>","<address>",
"<footer>","<header>","<hgroup>","<aside>","<article>","<nav>","<section>",
"<body>","<noscript>","<script>","<style>","<meta>","<link>","<base>",
"<title>","<head>","<html>"
);
$list = trim(strtolower($blacklisted));
$list = preg_replace('/[^a-z ]/i', '', $list);
$list = '<' . str_replace(' ', '> <', $list) . '>';
$list = array_map('trim', explode(' ', $list));
return array_diff($html5, $list);
}
$blacklisted = '<html> <bogus> <EM> em li ol';
$whitelist = blacklistElements($blacklisted);
if (count($errors)) {
echo "There were errors.\n";
print_r($errors);
echo "\n";
} else {
// Do strip_tags() ...
}
如果您传入不想允许的内容,它将以数组
形式返回HTML5元素列表,然后将其连接成字符串并馈入strip_tags()
函数进行处理。$stripped = strip_tags($html, implode('', $whitelist)));
买方自负
现在,我已经将这个东西拼凑在一起了,但我知道还有一些问题没有考虑到。例如,从$allowable_tags
参数的strip_tags()
手册页中可以看出:
注意:
此参数不应包含空格。
strip_tags()
将标签视为大小写不敏感的字符串,介于<
和第一个空格或>
之间。这意味着strip_tags("<br/>", "<br>")
将返回一个空字符串。
现在已经很晚了,由于某种原因我无法完全理解这对这种方法意味着什么。所以我必须明天再想一想。我还从这个MDN文档页面编译了函数的$html5
元素的HTML元素列表。眼尖的读者可能会注意到所有标记都是这种形式:
<tagName>
<tagName/>
的使用进行变化,以及一些比较奇怪的变体。当然,还有更多的标签在那里。
所以它可能还没有准备好用于生产环境。但你已经有了想法。首先,看一下别人对这个主题说了什么:
如何使用 PHP 去除 <script> 标签及其之间的内容?
以及
看起来你有两个选择,一个是正则表达式解决方案,以上两个链接都提供了。第二种方法是使用HTML Purifier。
如果你是为了除去脚本标记而不是消毒用户内容,则可以使用正则表达式解决方案。然而,正如每个人所警告的那样,如果你正在消毒输入,请使用 HTML Purifier。
PHP(5或更高版本)解决方案:
如果您想删除<script>
标签(或任何其他标签),并且您还想删除标签内的内容,则应使用以下方法:
选项1(最简单):
preg_replace('#<script(.*?)>(.*?)</script>#is', '', $text);
<?php
$html = "<p>Your HTML code</p><script>With malicious code</script>"
$dom = new DOMDocument();
$dom->loadHTML($html);
$script = $dom->getElementsByTagName('script');
$remove = [];
foreach($script as $item)
{
$item->parentNode->removeChild($item);
}
$html = $dom->saveHTML();
$html
将是:
"<p>Your HTML code</p>"
这是我用来剥禁止标签列表的方法,可以同时删除包裹内容的标签和包含内容的标签,还能去除多余的空白。
$description = trim(preg_replace([
# Strip tags around content
'/\<(.*)doctype(.*)\>/i',
'/\<(.*)html(.*)\>/i',
'/\<(.*)head(.*)\>/i',
'/\<(.*)body(.*)\>/i',
# Strip tags and content inside
'/\<(.*)script(.*)\>(.*)<\/script>/i',
], '', $description));
输入示例:
$description = '<html>
<head>
</head>
<body>
<p>This distinctive Mini Chopper with Desire styling has a powerful wattage and high capacity which makes it a very versatile kitchen accessory. It also comes equipped with a durable glass bowl and lid for easy storage.</p>
<script type="application/javascript">alert('Hello world');</script>
</body>
</html>';
输出结果:
<p>This distinctive Mini Chopper with Desire styling has a powerful wattage and high capacity which makes it a very versatile kitchen accessory. It also comes equipped with a durable glass bowl and lid for easy storage.</p>
我使用以下内容:
function strip_tags_with_forbidden_tags($input, $forbidden_tags)
{
foreach (explode(',', $forbidden_tags) as $tag) {
$tag = preg_replace(array('/^</', '/>$/'), array('', ''), $tag);
$input = preg_replace(sprintf('/<%s[^>]*>([^<]+)<\/%s>/', $tag, $tag), '$1', $input);
}
return $input;
}
然后你可以这样做:
echo strip_tags_with_forbidden_tags('<cancel>abc</cancel>xpto<p>def></p><g>xyz</g><t>xpto</t>', 'cancel,g');
输出:'abcxpto<p>def></p>xyz<t>xpto</t>'
echo strip_tags_with_forbidden_tags('<cancel>abc</cancel> xpto <p>def></p> <g>xyz</g> <t>xpto</t>', 'cancel,g');
'abc xpto <p>def></p> xyz <t>xpto</t>'
strip_tags()
来清除标记,请注意不要这么做。 - Jared FarrishHTML.ForbiddenElements
,我认为这将实现您想要的功能(黑名单而不是白名单元素)。个人建议仍然使用白名单,并使用帮助函数来给出黑名单组的反向结果。 - Jared FarrishHTML.ForbiddenElements
的array
值,请在答案下留言告诉我。 - Jared Farrish