考虑以下HTML Purifier设置:
require_once 'library/HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
$config->set('Core.EscapeInvalidTags', true);
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($dirty_html);
如果您运行以下案例:
$dirty_html = "<p>lorem <script>ipsum</script></p>";
//output
<p>lorem <script>ipsum</script></p>
正如预期的那样,它不是删除无效标签,而是将它们全部转义。
但是,请考虑以下其他测试用例:
案例1
$dirty_html = "<p>lorem <b>ipsum</p>";
//output
<p>lorem <b>ipsum</b></p>
//desired output
<p>lorem <b>ipsum</p>
案例2
$dirty_html = "<p>lorem ipsum</b></p>";
//output
<p>lorem ipsum</p>
//desired output
<p>lorem ipsum</b></p>
案例3
$dirty_html = "<p>lorem ipsum<script></script></p>";
//output
<p>lorem ipsum<script /></p>
//desired output
<p>lorem ipsum<script></script></p>
不是仅仅转义无效标签,而是先修复它们然后将其转义。这样事情会变得非常奇怪,例如:
案例4
$dirty_html = "<p><a href='...'><div>Text</div></a></p>";
//output
<p><a href="..."></a></p><div><a href="...">Text</a></div><a href="..."></a></p>
问题
因此,是否可以禁用语法修复并只是转义无效标记?
答案 0 :(得分:1)
您看到语法修复的原因是HTML Purifier接近HTML卫生主题的基本方式:首先解析HTML以理解它,然后决定哪一个要保留在已解析表示中的元素,然后呈现HTML。
您可能熟悉stackoverflow的一个most famous answers,这是一个有趣和恼怒的观察,真正的正则表达式无法解析HTML - 您需要额外的逻辑,因为HTML是一个上下文 - 免费语言,而不是常规语言。 (现代&#39;常规表达式不是正式的正则表达式,但这是另一回事。)换句话说,如果你真的想知道你的HTML中发生了什么 - 那么你正确地应用你的白名单或黑名单 - 你需要解析它,这意味着文本最终会以完全不同的方式呈现。
解析如何导致输入和输出之间发生变化的一个示例是HTML Purifier strips extraneous whitespace from between attributes,在您的情况下可能不会打扰您,但仍然源于HTML的解析表示与文本表示完全不同。它没有试图保留您输入的形式 - 它试图保留该功能。
当没有明确的功能并且必须开始猜测时,这会变得棘手。要选择一个示例,想象一下,在浏览HTML输入时,您会发现在不知名的地方看起来像一个开放的<td>
标记 - 如果有一个未公开的<td>
,您可以consider it valid只要你添加一个结束标记,就会标记一段时间,但如果你将第一个标记转义为<td>
,那么你会need to discard the text data that would have been in the <td>
- 因为 - 取决于浏览器呈现 - 它可能会将数据放入部分页面外部的视觉页面,即用户未明确提交的地点。
简而言之:您无法轻松删除所有语法修复和/或整理,而无需翻阅HTML Purifier的解析内容,并确保您找不到有价值的信息丢失。< / p>
那就是说,你可以尝试切换the underlying parsing engine with Core.LexerImpl ,看看它是否能让你获得更好的结果! :) DOMLex definitely adds missing ending nodes从一开始,但从粗略的一瞥,DirectLex可能不会。 HTMLPurifier's MakeWellFormed strategy class中存在大量自动关闭逻辑,这也可能对您造成问题。
根据为什么,您希望保留此数据(以便进行分析?),单独保存原始输入(同时保留HTML Purifier本身)可以为您提供更好的解决方案。< / p>