6

根据strip_tags文档,第二个参数采用允许的标签。但是在我的情况下,我想做相反的事情。假设我将接受script_tags通常(默认)接受的标签,但只<script>去除标签。有什么可能的方法吗?

我并不是说有人为我编写代码,而是非常感谢您提供有关如何实现此目标的可能方法(如果可能)。

4

5 回答 5

5

编辑

要使用 HTML PurifierHTML.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);

http://htmlpurifier.org/docs

HTML.ForbiddenElements 应设置为array. 我不知道array成员应该采取什么形式:

array('script','style','applet')

或者:

array('<script>','<style>','<applet>')

或者是其他东西?

认为这是第一种形式,没有分隔符;使用一种与TinyMCE语法HTML.AllowedElements有些共同的配置字符串形式:valid elements

tinyMCE.init({
    ...
    valid_elements : "a[href|target=_blank],strong/b,div[align],br",
    ...
});

所以我的猜测是它只是一个术语,不应该提供任何属性(因为你正在禁止元素......虽然也有一个HTML.ForbiddenAttributes)。但这是一个猜测。

我还将从HTML.ForbiddenAttributes文档中添加此注释:

警告:该指令是对 的补充%HTML.ForbiddenElements,因此,请查看该指令以讨论为什么在使用该指令之前应该三思而后行。

黑名单并不像白名单那样“强大”,但你可能有你的理由。请注意并小心。

没有测试,我不知道该告诉你什么。我会继续寻找答案,但我可能会先上床睡觉。很晚了。:)


尽管我认为您确实应该使用HTML Purifier并利用它的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() ...
}

http://codepad.org/LV8ckRjd

因此,如果您传入您不想允许的内容,它会以一种array形式返回 HTML5 元素列表,然后您可以strip_tags()在将其加入字符串后将其输入:

$stripped = strip_tags($html, implode('', $whitelist)));

买者自负

现在,我已经很好地解决了这个问题,我知道有些问题我还没有想到。例如,从参数的strip_tags()手册页$allowable_tags

笔记:

此参数不应包含空格。将标记视为与第一个空格或.strip_tags()之间的不区分大小写的字符串。这意味着返回一个空字符串。<>strip_tags("<br/>", "<br>")

已经很晚了,由于某种原因,我不太明白这对这种方法意味着什么。所以我明天必须考虑一下。$html5我还从这个MDN 文档页面编译了函数元素中的 HTML 元素列表。眼尖的读者可能会注意到所有标签都是这种形式:

<tagName>

我不确定这将如何影响结果,我是否需要考虑使用短标签的变化以及一些,咳咳,更奇怪的<tagName/>变化。当然,还有更多的标签

所以它可能还没有准备好生产。但你明白了。

于 2012-09-11T06:39:27.723 回答
2

首先,看看其他人对这个话题的看法:

用 PHP 去除 <script> 标签和介于两者之间的所有内容?

从 HTML 内容中删除脚本标签

看来您有 2 个选择,一个是正则表达式解决方案,上面的两个链接都给出了它们。二是使用HTML Purifier

如果您出于其他原因而不是清理用户内容而剥离脚本标签,那么正则表达式可能是一个很好的解决方案。但是,正如每个人都警告过的那样,如果您正在清理输入,那么使用 HTML Purifier 是一个好主意。

于 2012-09-11T04:12:18.360 回答
1

PHP(5或更高)解决方案:

如果要删除<script>标签(或任何其他标签),并且还想删除标签内的内容,则应使用:

选项 1(最简单):

preg_replace('#<script(.*?)>(.*?)</script>#is', '', $text);

选项 2(更通用):

<?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>"
于 2016-04-12T15:51:59.317 回答
0

这就是我用来删除禁止标签列表的方法,既可以删除包含内容的标签,也可以删除包含内容的标签,另外还可以修剪剩余的空白。

$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>
于 2016-03-15T10:35:08.300 回答
0

我使用以下内容:

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>'

于 2016-04-27T15:53:59.100 回答