我尝试将
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解决方案