我要说的是,当您将先前提交的数据加载到表单中时,输出周围没有htmlspecialchars() - 不过,您应该这样做,因为 它仍然是 text 用于 textarea。您的所见即所得将文本解释为 HTML,但不要将其与实际 HTML 混淆。 :)
作为安慰,您知道这种混淆非常普遍 (it keepshappening),而且有很多很多人的问题与您描述的完全一样。
让我们看一下工作流程以及可能出错的地方:
问题工作流程
当有人将 <tag> 写入您所见即所得字段中的富文本并加载所见即所得时,编辑器会看到有人想将 HTML <tag> 放入消息中。
当有人将粗体文本写入富文本时,编辑器会看到有人想将 HTML <b>bold text</b>(或类似的)放入消息中。
同时,在后台,文本&amp;lt;tag&amp;gt; &lt;b&gt;bold text&lt;/b&gt;(或其他)被存储在textarea中。为了在 HTML 上下文中将文本保留为 text,它使用 HTML 编码进行编码,不可见地将其转换为 &amp;lt;tag&amp;gt; &lt;b&gt;bold text&lt;/b&gt;。
但是,当您按下提交按钮时,文本区域 (&amp;lt;tag&amp;gt; &lt;b&gt;bold text&lt;/b&gt;) 的 文本 将发送到您的服务器,因为表单数据本身当然不是 HTML 编码的(它不是嵌入在 HTML 中)- 它只是一组键和值,而您想要 textarea 的值。
现在,当您在服务器端应用程序中构建 HTML 以再次加载消息以进行进一步编辑时,您希望字段的 值 进行 HTML 编码,因为您正在将该值放入 HTML 上下文中。您之前所做的是创建 <textarea>&lt;tag&gt; <b>bold text</b></textarea>,它将 HTML 放入 HTML 上下文中。在基本上所有浏览器中,这使得 textarea 采用 value <tag> <b>bold text</b>。哎哟! (想象一下,如果有人将</textarea> 作为其原始消息的一部分!)
令所有人感到困惑的是,所见即所得的编辑器很不幸地擅长在那里显示您想要的大致内容。对于大多数用例,您甚至不会注意到差异,这就是此错误如此普遍的原因。
但是,在构建页面的 HTML 时,您实际上想要构建 <textarea>&amp;lt;tag&amp;gt; &lt;b&gt;bold text&lt;/b&gt;</textarea>。这使得 textarea 具有 value &amp;lt;tag&amp;gt; &lt;b&gt;bold text&lt;/b&gt; - 这正是你想要的。
您当前的解决方案通过htmlspecialchars_decode() 运行提交的文本,这会将&lt;tag&gt; 变成&lt;tag&gt;,从而让HTML Purifier 消除它。您不再需要担心 &lt;tag&gt; 在所见即所得的上下文中被解释为 &lt;tag&gt;。
但是,很遗憾你有两个问题:
1) 如果没有 HTML Purifier 剥离它们,人们将无法再提交关于标签的消息。根据您的文本区域的用例,这可能不是问题。也许您不希望人们能够提交像 If you're making your own website, you can use &lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js" language="javascript"&gt; instead of hosting the jquery.js yourself 这样的 HTML 消息 - 使用您当前的解决方案,这样的消息将被 HTML Purifier 清理为 If you're making your own website, you can use instead of hosting the jquery.js yourself。
2) 更危险,人们仍然可以黑你!尝试将 text &amp;lt;script&amp;gt;alert(1);&amp;lt;/script&amp;gt; 写入您的编辑器(以便编辑器将您要提交的 HTML 视为&amp;lt;script&amp;gt;alert(1);&amp;lt;/script&amp;gt;)并点击提交。您的解决方案会将其转换为 &amp;lt;script&amp;gt;alert(1);&amp;lt;/script&amp;gt;,然后您将其放入您的 <textarea>,然后不幸的是您又回到了原点。
实际解决方案
删除您的htmlspecialchars_decode() 解决方案(但要保持净化!),而是将htmlspecialchars() 放在您的输出周围。您的所见即所得仍然可以工作,并且您不会再绕过 HTML Purifier 的卫生。