我使用@Alex's approach here使用内置的DOMDocument从HTML文档中删除脚本标签。问题是,如果我有一个包含Javascript内容的脚本标签,然后又有一个链接到外部Javascript源文件的脚本标签,则不是所有的脚本标签都已从HTML中删除。

$result = '
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>
            hey
        </title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <script>
            alert("hello");
        </script>
    </head>
    <body>hey</body>
</html>
';

$dom = new DOMDocument();
if($dom->loadHTML($result))
{
    $script_tags = $dom->getElementsByTagName('script');

    $length = $script_tags->length;

    for ($i = 0; $i < $length; $i++) {
        if(is_object($script_tags->item($i)->parentNode)) {
            $script_tags->item($i)->parentNode->removeChild($script_tags->item($i));
        }
    }

    echo $dom->saveHTML();
}

上面的代码输出:
<html>
    <head>
        <meta charset="utf-8">
        <title>hey</title>
        <script>
        alert("hello");
        </script>
    </head>
    <body>
        hey
    </body>
</html>

从输出中可以看到,仅除去了外部脚本标记。我有什么办法可以确保删除所有脚本标签?

最佳答案

您的错误实际上是微不足道的。当其父元素更改时,尤其是在其子级数更改时,会自动更新DOMNode对象(及其所有后代-DOMElementDOMNodeList和其他几个!)。这是写在PHP文档中的两行代码上的,但是大部分都笼罩在地毯下。

如果循环使用($k instanceof DOMNode)->length,然后从节点中删除元素,您会注意到length属性实际上发生了变化!我必须编写自己的库来抵消此问题和其他一些怪癖。

解决方案:

if($dom->loadHTML($result))
{
    while (($r = $dom->getElementsByTagName("script")) && $r->length) {
            $r->item(0)->parentNode->removeChild($r->item(0));
    }
echo $dom->saveHTML();

我实际上并没有在循环-只是一次弹出第一个元素。结果:http://sebrenauld.co.uk/domremovescript.php

关于php - DOMDocument从HTML源代码中删除脚本标签,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15925961/

10-11 00:42