是否有一个preg可以过滤php中的所有js脚本?

时间:2014-07-11 07:03:53

标签: php preg-match

我需要在php中过滤所有Js脚本,我有一个preg /<[^>]*?>.*?<\/>/si,但它不能正常工作。是否有一个好的preg可以过滤php中的所有js脚本?

1 个答案:

答案 0 :(得分:0)

此脚本将删除所有脚本元素以及&#39; onload&#39;中的任何内联脚本。或者&#39; onclick&#39;处理程序:

$tags = <<<'EOT'
<body onload="alert('onload');">
<div onclick="alert('onclick');">
    <script>alert('script');</script>
    <h1 onclick="alert('onclick');">heading</h1>
    content
</div>
<script>var that = this;</script>
<p>paragraph</p>
</body>
EOT;

$doc = new DOMDocument();
$doc->loadHTML($tags);

$scripts = $doc->getElementsByTagName('script');
// Loop through backwards otherwise item($i) will change
for ($i = $scripts->length - 1; $i >= 0; --$i) {
  $script = $scripts->item($i);
  $script->parentNode->removeChild($script);
}

// Not a built-in class
// see comments on http://php.net/manual/en/class.domnodelist.php
$rec = new DOMNodeRecursiveIterator($doc->getElementsByTagName('*'));
foreach ($rec as $node) {
  if ($node->nodeType === 1) {
    $node->removeAttribute('onload');
    $node->removeAttribute('onclick');
  }
}

$body = $doc->getElementsByTagName('body')->item(0);
echo $doc->saveHTML($body);

DOMDocument :: loadHTML将解析字符串$tags并创建DOMDocument对象。这样做时,它会创建一个有效的HTML文档,因此会添加一个doctype,一个<html>标记和一个<body>标记(如果它们尚不存在)。第一个循环从文档中删除所有<script>个元素。第二个循环以递归方式遍历DOM并删除所有“onload”&#39;和&#39; onclick&#39;内联处理程序。

如果您正在阅读完整的文档(而不仅仅是我的示例中的<body>),则可以将底线简化为echo $doc->saveHTML();

输出:

<body>
<div>
    <h1>heading</h1>
    content
</div>
<p>paragraph</p>

显然,这不是防弹的(例如,您可能希望删除其他属性),但它可能足以满足您的需求。 DOMDocument能够解析格式错误的HTML,因此它可能比任何依赖正则表达式的解决方案更灵活。