从HTML内容中删除脚本标记

I-M*_*-JM 56 php regex htmlpurifier

我正在使用HTML Purifier(http://htmlpurifier.org/)

我只是想删除<script>标签.我不想删除内联格式或任何其他东西.

我怎样才能做到这一点?

还有一件事,还有其他方法可以从HTML中删除脚本标记

Dej*_*vic 127

因为这个问题用标记,我将在这种情况下用穷人的解决方案回答:

$html = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $html);
Run Code Online (Sandbox Code Playgroud)

但是,正则表达式不是用于解析HTML/XML,即使你写出最终将会破坏的完美表达式,也不值得,但在某些情况下,快速修复某些标记很有用,而且快速修复时也是如此,忘记安全.仅对您信任的内容/标记使用正则表达式.

请记住,任何用户输入的内容都应被视为不安全.

这里更好的解决方案是使用DOMDocument专为此设计的解决方案.这是一个片段,演示了如何轻松,干净(与正则表达式相比),(几乎)可靠和(几乎)安全是这样做的:

<?php

$html = <<<HTML
...
HTML;

$dom = new DOMDocument();

$dom->loadHTML($html);

$script = $dom->getElementsByTagName('script');

$remove = [];
foreach($script as $item)
{
  $remove[] = $item;
}

foreach ($remove as $item)
{
  $item->parentNode->removeChild($item); 
}

$html = $dom->saveHTML();
Run Code Online (Sandbox Code Playgroud)

我故意删除了HTML,因为即使这样也可以使用bork.

  • 我很久以前就看到了那个讨论,你应该阅读它,而不仅仅是看到它. (41认同)
  • -1表示RegExp解决方案.参见[this discussion](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454). (11认同)
  • 虽然我很感激你的冷漠反应,但我拒绝你答案的理由是合理的.请参阅[this gist](https://gist.github.com/42e3f06274d5df814cf1),了解制作的脚本标记,它可以绕过您的正则表达式.公平地说,它可能更多地是你的特定正则表达式的缺点而不是完全放弃正则表达式的理由.但是,对我来说同样有趣. (9认同)
  • 如果你想采用正则表达式路由,请确保多次运行`prey_replace`直到输出不再改变(从@ParijatKalia捕获示例输入). (4认同)
  • @Arth因为你得不到正确的结果(迭代器的行为不像预期的那样),请参阅[this](http://php.net/manual/en/domnode.removechild.php#90292)评论. (3认同)
  • 这个特殊的正则表达式是_vulnerable_到javascript注入. (2认同)

Ale*_*lex 37

使用PHP DOMDocument解析器.

$doc = new DOMDocument();

// load the HTML string we want to strip
$doc->loadHTML($html);

// get all the script tags
$script_tags = $doc->getElementsByTagName('script');

$length = $script_tags->length;

// for each tag, remove it from the DOM
for ($i = 0; $i < $length; $i++) {
  $script_tags->item($i)->parentNode->removeChild($script_tags->item($i));
}

// get the HTML string back
$no_script_html_string = $doc->saveHTML();
Run Code Online (Sandbox Code Playgroud)

这让我使用以下HTML文档:

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>
            hey
        </title>
        <script>
            alert("hello");
        </script>
    </head>
    <body>
        hey
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

请记住,DOMDocument解析器需要PHP 5或更高版本.

  • @mmmshuddup,`libxml_use_internal_errors(true);`可能有帮助. (6认同)
  • +0我厌倦了关于正则表达式和HTML的讨论.在_some_非常特殊的场合,使用正则表达式应该没问题.在我的情况下,我收到此错误:`警告:DOMDocument :: loadHTML()[domdocument.loadhtml]:在实体`中标记myCustomTag无效.尝试了一切.我想要做的就是删除应用程序的一小部分的脚本标记(_without_花费更多的时间).我将使用preg_replace,就是这样.我不想再听到有关它的消息.:) (5认同)
  • 请参阅我对所选最佳答案的评论.我更愿意看到编码员覆盖一般情况,因为恶意用户可以变得非常聪明.但是,你是对的:例如,在开发内部应用程序时,忽略这些漏洞并使用正则表达式可能会被认为是可以的. (2认同)

小智 5

$html = <<<HTML
...
HTML;
$dom = new DOMDocument();
$dom->loadHTML($html);
$tags_to_remove = array('script','style','iframe','link');
foreach($tags_to_remove as $tag){
    $element = $dom->getElementsByTagName($tag);
    foreach($element  as $item){
        $item->parentNode->removeChild($item);
    }
}
$html = $dom->saveHTML();
Run Code Online (Sandbox Code Playgroud)