在网站运营中,我们经常会遇到需要输出包含HTML代码的内容的情况。例如,文章正文中的图片、链接,或者自定义的样式布局等。当您在AnQiCMS模板中输出这些内容时,可能会发现它们并没有按预期显示为可交互的元素,而是以原始的HTML代码形式展现出来,比如 <p>这是一个段落</p> 变成了 &lt;p&gt;这是一个段落&lt;/p&gt;。这正是我们今天要探讨的核心问题:如何在AnQiCMS模板中安全地输出包含HTML代码的内容,避免被转义。

AnQiCMS模板内容的默认行为

AnQiCMS的模板引擎在设计时,将网站的安全性放在了非常重要的位置。出于对跨站脚本攻击(XSS)的防范,它默认会对模板中输出的所有内容进行HTML转义。这意味着,任何被识别为HTML标签的特殊字符,例如 <>&"',都会被自动转换为它们对应的HTML实体形式。

例如,一个原本是 <script>alert('Hello!')</script> 的内容,在默认转义后会变为 &lt;script&gt;alert(&#39;Hello!&#39;)&lt;/script&gt;。这样,浏览器就不会将其作为可执行的脚本来处理,而是将其作为纯文本显示,从而有效地阻止了恶意代码的执行。这是一种非常稳健的安全策略。

然而,对于那些我们确实希望以HTML形式呈现的合法内容,例如在后台富文本编辑器中精心排版的内容,这种默认的转义行为就需要我们进行额外处理,以解除这种“安全束缚”。

解决方案一:使用 safe 过滤器解除默认转义

当您明确知道某个变量中包含的HTML代码是安全且可信的,并且希望浏览器能直接解析并渲染它们时,AnQiCMS提供了 safe 过滤器来处理这种情况。它的作用是告诉模板引擎:“这段内容是安全的,请不要对其进行HTML转义,直接按原样输出吧!”

  • 使用方法safe 过滤器的使用非常简单直观。您只需要在需要解除转义的变量后面加上 |safe 即可。例如,如果您有一个名为 archiveContent 的变量存储着文章的正文HTML,你可以这样输出它:

    <div>{{ archiveContent|safe }}</div>
    

    这里,archiveContent 中的所有HTML标签都将被浏览器正常解析和渲染。

  • 安全警示: 尽管 safe 过滤器提供了便利,但其使用并非没有风险。一旦您使用了 |safe,就意味着您向模板引擎担保了这段内容的安全性。如果 archiveContent 中不小心包含了未经严格审查的恶意脚本,那么这些脚本将会被浏览器执行,从而导致严重的XSS攻击,可能泄露用户信息或破坏网站功能。因此,在使用 safe 过滤器之前,务必确认内容来源是绝对可靠和安全的,或者内容本身已经经过了严格的过滤和验证

解决方案二:使用 render 过滤器处理Markdown内容

在AnQiCMS中,您可能会利用其强大的内容模型功能,通过Markdown编辑器来撰写文章或页面内容。Markdown是一种轻量级标记语言,它通过简单的符号(如 # 表示标题,* 表示斜体)来快速实现排版。当这些Markdown格式的内容需要在前端显示为格式化的HTML时,AnQiCMS提供了 render 过滤器来完成这个转换工作。

  • 使用方法render 过滤器会将Markdown文本处理并转换为相应的HTML结构。由于转换后的结果是HTML,通常也需要配合 safe 过滤器一起使用,以确保转换后的HTML标签能够被浏览器正确解析,而不是再次被转义。
    • 例如,如果 categoryContent 变量存储着Markdown格式的分类介绍,您可以这样输出它:
      
      <div>{{ categoryContent|render|safe }}</div>
      
    • 在这个例子中,|render 过滤器首先将Markdown文本处理并转换成HTML,然后 |safe 过滤器确保这些HTML标签能被浏览器正常解析和显示。值得注意的是,AnQiCMS后台内容管理中的某些核心字段(如“文档内容”、“分类内容”等),当你在后台启用了Markdown编辑器后,系统可能会在内容进入模板之前就自动完成了Markdown到HTML的转换。但在处理自定义字段或需要明确控制渲染行为时,在模板中显式使用 render 过滤器仍然是推荐的做法。

实践中的注意事项

在AnQiCMS模板中输出包含HTML代码的内容时,为了确保网站的安全性和稳定性,请务必注意以下几点:

  1. 信任源头:只对您完全信任的内容源使用 safe 过滤器。例如,由网站管理员在后台通过富文本编辑器编辑并发布的内容,由于通常经过了系统内置的安全过滤,可以认为是安全的。
  2. 谨慎处理用户输入:对于任何来自用户前端提交的、未经处理的HTML内容(如评论、留言等),绝不能直接通过 |safe 过滤器输出。这是最常见的XSS攻击入口。如果确实需要显示用户提交的包含HTML的内容,必须在服务端进行严格的内容清理和过滤,例如使用HTML白名单机制,只允许显示安全的HTML标签和属性,去除所有潜在的恶意脚本