You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flask-WTF中自定义验证错误消息并避免HTML被转义

问题原因

Flask-WTF 依赖 Jinja2 模板引擎渲染内容,默认开启全局自动转义,所有包含HTML标签的字符串会被转义为普通文本输出,避免不可信内容造成XSS漏洞,因此直接在ValidationError中传入的HTML标签不会被解析为富文本。

解决方案

两种方案按需选择即可,注意所有允许渲染HTML的场景都要确保内容完全可信,禁止把用户可控的未过滤内容直接标记为安全内容。

方案1:后端标记错误消息为安全内容(推荐)

从抛出验证错误的源头,用markupsafe库的Markup类包裹带HTML的错误字符串,这个类会被Jinja2识别为可信内容,渲染时不会转义,Flask全生态组件都兼容这个标记方式,不需要额外改模板。
修改后的验证器代码如下:

from markupsafe import Markup
from wtforms.validators import ValidationError

def is_some_condition_true(arg: str) -> bool:
    return arg == "example"

def validation_func(self, arg: str) -> None:
    if not is_some_condition_true(arg):
        raise ValidationError(Markup("The <strong>validation</strong> failed"))

适合错误消息固定、HTML内容完全由开发者控制的场景。

方案2:模板渲染时手动指定不转义

如果不想修改后端验证逻辑,可以在模板输出错误消息时,给变量加|safe过滤器,告诉Jinja2该内容不需要转义。
模板中渲染错误的示例代码:

<!-- 单个字段错误渲染示例 -->
<div class="form-field">
    {{ form.target_field.label }}
    {{ form.target_field() }}
    {% for error in form.target_field.errors %}
        <p class="error-tip">{{ error|safe }}</p>
    {% endfor %}
</div>

适合需要灵活控制哪些位置渲染富文本、哪些位置保留纯文本的场景。

注意事项
  • 不要对包含用户提交内容的错误消息使用上述两种方案,否则可能引发XSS注入漏洞
  • 不要用手动给字符串拼接__html__属性的野路子绕过转义,使用官方提供的Markup类兼容性最好,不会出现版本兼容问题

内容的提问来源于stack exchange,提问作者965311532

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 08:12:11