PHP 5.4.16 DOMDocument删除部分Javascript

我尝试将
HTML页面从远程服务器加载到
PHP脚本中,该脚本应该使用DOMDocument类操作HTML.但我已经看到,DOMDocument类删除了HTML页面附带的
Javascript的一些部分.有一些事情,如:

<script type="text/javascript">
//...
function printJSPage() {
    var printwin=window.open('','haha','top=100,left=100,width=800,height=600');
    printwin.document.writeln(' <table border="0" cellspacing="5" cellpadding="0" width="100%">');
    printwin.document.writeln(' <tr>');
    printwin.document.writeln(' <td align="left" valign="bottom">');
    //...
    printwin.document.writeln('</td>');
    //...
}
</script>

但DOMDocument改变了即行

printwin.document.writeln('</td>');

printwin.document.writeln(' ');

还有很多其他东西(即最后一个脚本标签不再存在.结果我得到一个完整的被破坏的页面,我无法进一步发送.

所以我认为,DOMDocument在Javascript代码中的HTML标记存在问题,并尝试更正代码,以生成格式良好的文档.我可以阻止DOMDocument中的Javascript解析吗?

PHP代码片段是:

$stdin = file_get_contents('php://stdin');
$dom = new \DOMDocument();
@$dom->loadHTML($stdin);
return $dom->saveHTML();   // will produce wrong HTML
//return $stdin;           // will produce correct HTML

我已经存储了两个HTML版本,并将它们与Meld进行了比较.

我也测试过了

@$dom->loadXML($stdin);
return $dom->saveHTML();

但是我没有从对象那里得到任何东西.

最佳答案 这是一个可能有用的黑客攻击.我们的想法是用一个字符串替换脚本内容,该字符串保证是有效的HTML并且是唯一的,然后将其替换回来.

它将脚本标记内的所有内容替换为这些内容的MD5,然后将其替换回来.

$scriptContainer = [];
$str = preg_replace_callback ("#<script([^>]*)>(.*?)</script>#s", function ($matches) use (&$scriptContainer) {
     $scriptContainer[md5($matches[2])] = $matches[2];
        return "<script".$matches[1].">".md5($matches[2])."</script>";
    }, $str);
$dom = new \DOMDocument();
@$dom->loadHTML($str);
$final = strtr($dom->saveHTML(), $scriptContainer); 

这里strtr很方便,因为数组的格式,使用str_replace(array_keys($scriptContainer),$scriptContainer,$dom-> saveHTML())也可以.

我发现PHP无法正确解析HTML内容,这一点令人惊讶.它似乎是在解析XML内容(错误地也是如此,因为CDATA内容被解析而不是按字面处理).然而它就是它的本质,如果你想要一个真正的文档解析器,那么你应该用jsdom查看Node.js解决方案

点赞